Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 计算行对的出现次数_Sql_Sql Server 2008_Join_Group By - Fatal编程技术网

Sql 计算行对的出现次数

Sql 计算行对的出现次数,sql,sql-server-2008,join,group-by,Sql,Sql Server 2008,Join,Group By,我有一个事件驱动的表,即当事件发生时,它会被更新。当事件“开始”出现时,它会记录一个人的位置,而“结束”出现时,它不会记录 我想计算结束的数量,但报告“开始”事件中记录的相应位置 注意:我想忽略其他类型的事件 Table drop table Events; CREATE TABLE Events ( EventName VARCHAR(10) NOT NULL, EventPersonName VARCHAR(50) NOT NULL, EventP

我有一个事件驱动的表,即当事件发生时,它会被更新。当事件“开始”出现时,它会记录一个人的位置,而“结束”出现时,它不会记录

我想计算结束的数量,但报告“开始”事件中记录的相应位置

注意:我想忽略其他类型的事件

Table

drop table Events; 
CREATE TABLE Events (
    EventName       VARCHAR(10) NOT NULL, 
    EventPersonName VARCHAR(50) NOT NULL, 
    EventPersonLocation VARCHAR(50) NULL, 
    EventDate       DATETIME2(0) NULL
);

INSERT  Events 
SELECT 'end', 'bob', 'Null', '2014-05-27 08:00' UNION ALL 
SELECT 'end', 'sally', 'null', '2014-05-27 07:00' UNION ALL 
SELECT 'Start', 'sally', 'Sydney', '2014-05-27 06:30' UNION ALL

SELECT 'start', 'bob', 'Belfast', '2014-05-27 06:00' UNION ALL 
SELECT 'end', 'sally', 'null', '2014-05-27 05:00' UNION ALL 
SELECT 'start', 'jack', 'London', '2014-05-27 04:00' UNION ALL 
SELECT 'end', 'john', 'null', '2014-05-27 03:00' UNION ALL 
SELECT 'start', 'sally', 'New Yourk', '2014-05-27 02:00' UNION ALL 
SELECT 'start', 'john', 'Dublin', '2014-05-27 01:00';
我如何找到自2014/05/27 00:30以来完成的数值,结果会是什么

John, Dublin
Sally, New York
Sally, Sydney
Bob, Belfast

我怀疑我必须将表连接到它本身,这将为每个开始和结束提供一行,然后我可以简单地获取我需要的详细信息,但是由于时间过滤器,没有结束的开始和没有开始的结束如何?此查询将为您提供所需的结果:

SELECT
  s.eventPersonName,
  s.eventPersonLocation,
  s.eventDate AS startDate,
  e.eventDate AS endDate
FROM events e
JOIN events s ON
  s.eventPersonName=e.eventPersonName AND
  s.eventName      ='start'           AND
  s.eventDate = (
    SELECT MAX(p.eventDate)
    FROM events p
    WHERE
      p.eventPersonName=e.eventPersonName AND
      p.eventDate<e.eventDate)
WHERE e.eventName='end';
我已经试过了

考虑事项:

此查询只考虑那些尊重起始端预期序列的事件。所以,如果对某些人来说,你有像“开始-结束-开始”这样的部分数据,它将忽略前面紧跟着“结束”的“结束”和后面紧跟着“开始”的“开始”。如果可以改变行为,但在我看来,这是一个足够好的方法


如果您有相同日期时间的同一个人的事件,此查询可能会执行一些奇怪的操作。它在MAXeventDate上包含一个联接,在这种情况下会产生多行。

此查询将提供所需的结果:

SELECT
  s.eventPersonName,
  s.eventPersonLocation,
  s.eventDate AS startDate,
  e.eventDate AS endDate
FROM events e
JOIN events s ON
  s.eventPersonName=e.eventPersonName AND
  s.eventName      ='start'           AND
  s.eventDate = (
    SELECT MAX(p.eventDate)
    FROM events p
    WHERE
      p.eventPersonName=e.eventPersonName AND
      p.eventDate<e.eventDate)
WHERE e.eventName='end';
我已经试过了

考虑事项:

此查询只考虑那些尊重起始端预期序列的事件。所以,如果对某些人来说,你有像“开始-结束-开始”这样的部分数据,它将忽略前面紧跟着“结束”的“结束”和后面紧跟着“开始”的“开始”。如果可以改变行为,但在我看来,这是一个足够好的方法


如果您有相同日期时间的同一个人的事件,此查询可能会执行一些奇怪的操作。它在MAXeventDate上包含一个联接,在这种情况下可能会生成多行。

尝试此操作,它仅显示已完成事件的人员:事件总数=0:

更新的解决方案:

输出:

EventPersonName EventNum StartDate              EndDate                EventPersonLocation
--------------- -------- ---------------------- ---------------------- -------------------
bob             1        2014-05-27 06:00:00    2014-05-27 08:00:00    Belfast
john            1        2014-05-27 01:00:00    2014-05-27 03:00:00    Dublin
sally           1        2014-05-27 02:00:00    2014-05-27 05:00:00    New Yourk
sally           2        2014-05-27 06:30:00    2014-05-27 07:00:00    Sydney
如果只想显示人员姓名,则可以使用:

SELECT  y.EventPersonName
FROM (
    SELECT  x.EventPersonName, 
            EventWithSign = CASE WHEN x.EventName = 'start' THEN +1 WHEN x.EventName = 'end' THEN -1 ELSE 1/0 END
    FROM    @Events x
) y
GROUP BY y.EventPersonName
HAVING  SUM(y.EventWithSign) = 0

尝试此操作-仅显示已完成事件的人员:事件总数=0:

更新的解决方案:

输出:

EventPersonName EventNum StartDate              EndDate                EventPersonLocation
--------------- -------- ---------------------- ---------------------- -------------------
bob             1        2014-05-27 06:00:00    2014-05-27 08:00:00    Belfast
john            1        2014-05-27 01:00:00    2014-05-27 03:00:00    Dublin
sally           1        2014-05-27 02:00:00    2014-05-27 05:00:00    New Yourk
sally           2        2014-05-27 06:30:00    2014-05-27 07:00:00    Sydney
如果只想显示人员姓名,则可以使用:

SELECT  y.EventPersonName
FROM (
    SELECT  x.EventPersonName, 
            EventWithSign = CASE WHEN x.EventName = 'start' THEN +1 WHEN x.EventName = 'end' THEN -1 ELSE 1/0 END
    FROM    @Events x
) y
GROUP BY y.EventPersonName
HAVING  SUM(y.EventWithSign) = 0

一个非常简单的方法是说:在该人员存在后续事件的情况下,每次开始:

SELECT EventPersonName, EventPersonLocation 
FROM Events start_events
WHERE EventName = 'start'
AND EXISTS
(
  SELECT *
  FROM Events end_events
  WHERE end_events.EventPersonName = start_events.EventPersonName
  AND end_events.EventDate > start_events.EventDate
  AND end_events.EventName = 'end'
);

一个非常简单的方法是说:在该人员存在后续事件的情况下,每次开始:

SELECT EventPersonName, EventPersonLocation 
FROM Events start_events
WHERE EventName = 'start'
AND EXISTS
(
  SELECT *
  FROM Events end_events
  WHERE end_events.EventPersonName = start_events.EventPersonName
  AND end_events.EventDate > start_events.EventDate
  AND end_events.EventName = 'end'
);

所以你只想要结束行?或者你想让每个用户都在A和B时间之间,然后根据用户的最新开始位置、结束计数等度量?有趣的问题。。。但是标题真的很糟糕:所以你只想要结尾行?或者你想让每个用户都在A和B时间之间,然后根据用户的最新开始位置、结束计数等度量?有趣的问题。。。但标题真的很糟糕:只是想把它融入我的模型。我在if-else中打1/0,它说我不能除以零。这应该是什么?对不起,现在应该修改。本质上,我想展示的是,需要相同的名字,有超过1组的条目。。。对于您提供的更正数据,查询似乎正是您所期望的。我们能整理一下这些评论吗?只是想把它融入我的模型。我在if-else中打1/0,它说我不能除以零。这应该是什么?对不起,现在应该修改。本质上,我想展示的是,需要相同的名字,有超过1组的条目。。。对于您提供的更正数据,查询似乎正是您所期望的。我们能整理一下这些评论吗?嘿,thanx,但这不适用于修改后的示例,它是相同的过程,但有更多的线条,但是。。。。道歉我在示例中添加了一组新行,以帮助更好地描述问题:sally有两组完整的条目。我试过这个脚本,但它似乎打破了你的脚本-也许我错过了一些东西,但1/0是一个零除,如果有超过2个条目,每个人,然后它找不到这些entries@Fearghal; 查看我的更新解决方案。注意:null的文本为null,不带单引号,不是“null”或“null”。嘿,thanx,但这不适用于修改后的示例,该示例是相同的过程,但有更多行,但。。。。道歉我在示例中添加了一组新行,以帮助更好地描述问题:sally有两组完整的条目。我试过这个脚本,但它似乎打破了你的脚本-也许我错过了一些东西,但1/0是一个零除,如果有超过2个条目,每个人,然后它找不到这些entries@Fearghal; 查看我的更新解决方案。注意:null的文本为null,不带单引号,不带“null”或“null”。