我有一组数据如下,显示了谁用记录做了什么的历史。每个记录的唯一标识符显示在“ID”中,“Rec No”是分配给与记录的每次交互的序号。
ID Rec No Who Type
1 1 Bob New
1 2 Bob Open
1 3 Bob Assign
1 4 Sarah Add
1 5 Bob Add
1 6 Bob Close
2 1 John New
2 2 John Open
2 3 John Assign
2 4 Bob Assign
2 5 Sarah Add
2 6 Sarah Close
3 1 Sarah New
3 2 Sarah Open
3 3 Sarah Assign
3 4 Sarah Close
我需要找到所有'分配'操作。但是,如果多个“分配”在某个ID中,我想找到第一个。然后我也想找到那个人的名字。
因此,从上述日期开始,我希望输出为 -
Who Count (assign)
Bob 1
John 1
Sarah 1
我目前的代码是 -
SELECT IH.WHO, Count(IH.ID)
FROM Table.INCIDENTS_H IH
WHERE (IH.TYPE = Assign)
GROUP BY IH.WHO
但这会将输出显示为 -
Who Count (assign)
Bob 2
John 1
Sarah 1
因为它发现Bob在ID 2,Rec No 4上做了一个分配。
任何帮助将不胜感激。我正在使用MS SQL。
答案 0 :(得分:1)
我认为这样的事情就是你所追求的:
select
who, count(id)
from (
select ID, Who, row_number() over (partition by ID order by Rec) [rownum]
from Table.INCIDENTS_H IH
WHERE (IH.TYPE = Assign)
) a
where rownum = 1
group by who
这应该只计算每个ID组中的第一个Assign(按Rec排序)。
答案 1 :(得分:1)
您可以使用row_number来完成此操作
WITH INCIDENTS_H as (
SELECT
1 as ID, 1 as RecNo, 'Bob' as Who, 'New' as type
UNION ALL SELECT 1, 2, 'Bob','Open'
UNION ALL SELECT 1, 3, 'Bob','Assign'
UNION ALL SELECT 1, 4, 'Sarah','Add'
UNION ALL SELECT 1, 5, 'Bob','Add'
UNION ALL SELECT 1, 6, 'Bob','Close'
UNION ALL SELECT 2, 1, 'John','New'
UNION ALL SELECT 2, 2, 'John','Open'
UNION ALL SELECT 2, 3, 'John','Assign'
UNION ALL SELECT 2, 4, 'Bob','Assign'
UNION ALL SELECT 2, 5, 'Sarah','Add'
UNION ALL SELECT 2, 6, 'Sarah','Close'
UNION ALL SELECT 3, 1, 'Sarah','New'
UNION ALL SELECT 3, 2, 'Sarah','Open'
UNION ALL SELECT 3, 3, 'Sarah','Assign'
UNION ALL SELECT 3, 4, 'Sarah','Close')
, GetTheMin AS (
SELECT
ROW_NUMBER() over (partition by id order by recno) row,
ID,
RecNo,
Who,
type
FROM
INCIDENTS_H
WHERE
type = 'Assign'
)
SELECT Who,
COUNT(ID)
FROM GetTheMin
WHERE
row = 1
GROUP BY
who
或者你可以使用CROSS Apply
SELECT
who,
COUNT(id) id
FROM
(SELECT DISTINCT
MinValues.*
FROM
INCIDENTS_H h
CROSS APPLY ( SELECT TOP 1 *
FROM INCIDENTS_H h2
WHERE h.id = h2.id
ORDER BY ID, RecNo asc) MinValues) getTheMin
GROUP BY WHO
或者您可以使用Min使用标准SQL John Fisher的答案演示
答案 2 :(得分:1)
应该这样做:
SELECT IH.WHO, COUNT(IH.ID)
FROM INCIDENTS_H IH
JOIN (
SELECT ID, MIN([Rec No]) [Rec No]
FROM INCIDENTS_H
WHERE ([Type] = 'Assign')
GROUP BY ID
) IH2
ON IH2.ID = IH.ID AND IH2.[Rec No] = IH.[Rec No]
GROUP BY IH.WHO
答案 3 :(得分:1)
以下是表格中与“首次分配”要求相符的所有内容的视图:
select a.*
from Table.INCIDENTS_H a
inner join
(select ID, min([Rec No]) [Rec No] from Table.INCIDENTS_H where Type = 'Assign' group by ID) b
on a.ID = b.ID and a.[Rec No] = b.[Rec No]
结果:
ID Rec No Who Type
1 3 Bob Assign
2 3 John Assign
3 3 Sarah Assign
答案 4 :(得分:0)
select * from
(select
id, rec_no, who
from
operation_history
where
type = 'Assign'
order by rec_no asc) table_alias
group by
id
order by id asc
经过测试,结果如下:
id rec_no who
1 3 Bob
2 3 John
3 3 Sarah
(不是特定于SQL Server的代码)
答案 5 :(得分:0)
以下是原始帖子中提到的虚拟测试数据的查询:
with T (ID, RecNo, Who, Type) as
(
select 1, 1, 'Bob', 'New' union all
select 1, 2, 'Bob', 'open' union all
select 1, 3, 'Bob', 'Assign' union all
select 1, 4, 'Sarah', 'Add' union all
select 1, 5, 'Bob', 'Add' union all
select 1, 6, 'Bob', 'Close' union all
select 2, 1, 'John', 'New' union all
select 2, 2, 'John', 'Open' union all
select 2, 3, 'John', 'Assign' union all
select 2, 4, 'Bob', 'Assign' union all
select 2, 5, 'Sarah', 'Add' union all
select 2, 6, 'Sarah', 'Close' union all
select 3, 1, 'Sarah', 'New' union all
select 3, 2, 'Sarah', 'Open' union all
select 3, 3, 'Sarah', 'Assign' union all
select 3, 4, 'Sarah', 'Close'
)
select top 1 with ties *
from T
where Type = 'Assign'
order by row_number() over(partition by ID order by RecNo)
可以应用于问题的真实情况的“select”语句可能如下所示:
SELECT TOP 1 WITH TIES
IH.ID, IH.[Rec No], IH.WHO, IH.TYPE
FROM Table.INCIDENTS_H IH
WHERE IH.TYPE = 'Assign'
ORDER BY ROW_NUMBER() OVER(PARTITION BY IH.ID ORDER BY IH.[Rec No]);