我在这个网站上经历过很多问题,但是无法找到解决方案。 我有一张桌子:
Date GroupID CHANNEL 24/02/2015 1 A 26/02/2015 1 B 27/02/2015 1 C 21/03/2015 2 D 20/02/2015 3 E 25/02/2015 3 D 28/02/2015 4 C 04/03/2015 5 B 05/03/2015 5 E 10/03/2015 5 D 11/03/2015 5 A 14/03/2015 5 C 23/03/2015 5 F 28/03/2015 6 E
频道仅限于'A','B','C','D','E','F'。它中有很多行有不同的GROUPID。
我需要得到这张桌子:
Date GroupID Channel isFirst isLast Channelsingroup Daysbeforelast 24/02/2015 1 A TRUE FALSE 3 3 26/02/2015 1 B FALSE FALSE 3 1 27/02/2015 1 C FALSE TRUE 3 0 21/03/2015 2 D TRUE TRUE 1 0 20/02/2015 3 E TRUE FALSE 2 5 25/02/2015 3 D FALSE FALSE 2 0 28/02/2015 4 C TRUE TRUE 1 0 04/03/2015 5 B TRUE FALSE 6 19 05/03/2015 5 E FALSE FALSE 6 18 10/03/2015 5 D FALSE FALSE 6 13 11/03/2015 5 A FALSE FALSE 6 12 14/03/2015 5 C FALSE FALSE 6 9 23/03/2015 5 F FALSE FALSE 6 0 28/03/2015 6 E TRUE TRUE 1 0
<li>
</li><li>
</li>
当Channel是具有按时间排序的相同ID的行组中的第一个时;否则为假。
.container li{
list-style-type: none;
float:left;
padding: 5px 12px;
display: inline-block;
position: relative;
width: 20%
}
当Channel是具有按时间排序的相同GroupID的行组中的最后一个;否则为假。
IsFirst = TRUE
- 同一组中的行数(具有相同的GroupID)
IsLast = TRUE
- 在该组的最新一行与当前行之间的天数中的约会。
我无权创建或更新表,只能选择。
我希望以上数据有意义,有任何问题请告诉我。
答案 0 :(得分:4)
一种解决方案可能是使用窗口聚合函数:
select
*,
case when date = MIN(date) over (partition by groupid order by groupid) then 'TRUE' else 'FALSE' end isFirst,
case when date = MAX(date) over (partition by groupid order by groupid) then 'TRUE' else 'FALSE' end isLast,
count(*) over (partition by groupid order by groupid) Channelsingroup,
datediff(day,date,MAX(date) over (partition by groupid order by groupid)) Daysbeforelast
from your_table
答案 1 :(得分:3)
您可以使用ROW_NUMBER
获取isFirst
和isLast
列以及COUNT(*) OVER()
的{{1}}。此外,您可以使用ChannelsInGroup
来计算CROSS APPLY
:
DaysBeforeLast
<强>结果强>
WITH Cte AS(
SELECT *,
RN = ROW_NUMBER() OVER(PARTITION BY GroupID ORDER BY [Date]),
CC = COUNT(*) OVER(PARTITION BY GroupID)
FROM TestData
)
SELECT
c.[Date],
c.GroupID,
c.Channel,
isFirst = CASE WHEN c.RN = 1 THEN 'TRUE' ELSE 'FALSE' END,
isLast = CASE WHEN c.RN = c.CC THEN 'TRUE' ELSE 'FALSE' END,
ChannelsInGroup = c.CC,
DaysBeforeLast = DATEDIFF(DAY, c.[Date], x.LastDate)
FROM Cte c
CROSS APPLY(
SELECT TOP 1 [Date]
FROM Cte
WHERE
RN = CC
AND GroupID = c.GroupID
ORDER BY [Date] DESC
)x(LastDate)
答案 2 :(得分:0)
试试这个。
select DATE_1 ,GroupID,CHANNEL
, case (select top 1 test.CHANNEL
from test
where test.GroupID = outer1.GroupID
order by test.CHANNEL) when outer1.CHANNEL then 'true' else 'false' end as isFirst
, case (select top 1 test.CHANNEL
from test
where test.GroupID = outer1.GroupID
order by test.CHANNEL desc) when CHANNEL then 'true' else 'false' end as isLast
, (select count(*)
from test
where test.GroupID = outer1.GroupID) Channelsingroup
, (select DATEDIFF(DAY,outer1.DATE_1,MAX(test.DATE_1))
from test
where test.GroupID = outer1.GroupID)
from test outer1
答案 3 :(得分:0)
with cte
as
(select Date,GroupID ,Channel,row_number() over (partition by groupid order
by groupid) as first
from table1)
select Date,GroupID, Channel, case when first=1 then 'true' else 'false' end as
isFirst,
case when isfirst=b.Channelsingroup then 'true' else 'false' end as isLast
b.Channelsingroup, datediff(dd,getdate(),Daysbeforelast) as Daysbeforelast
from cte a
inner join (select count(*) as Channelsingroup ,max(date) as Daysbeforelast
from table1 group by groupid) as b
on a.groupid=b,groupid