我有一张像这样的表table1
:
sl next day count status
--------------------------
A 1 1 1 Yes
A 1 1 2 Yes
A 1 1 3 Yes
A 1 1 4 Yes
A 1 2 1 Yes
A 1 2 2 No
A 1 2 3 Yes
A 1 2 4 Yes
A 2 1 1 Yes
A 2 1 2 Yes
A 2 1 3 Yes
A 2 1 4 Yes
和输出应该是:
sl next status daylist
------------------------------
A 1 Yes 1-All
2-1,3,4
A 1 No 2-2
A 2 Yes 1-All
当您看到输出时,daylist
是计数和日期的组合,按status
每next
级别分组。
任何人都可以帮助我在T-SQL中实现这一目标吗?
提前致谢!
答案 0 :(得分:3)
这种事情应该在应用程序层而不是sql中完成。
使用stuff()
with select ... for xml path ('')
method of string concatenation和common table expression进行两步连接:
with cte as (
select
sl
, next
, status
, day
, daylist = stuff((
select
','+convert(varchar(10),i.count)
from t as i
where t.status = i.status
and t.day = i.day
and t.next = i.next
order by i.count
for xml path (''), type).value('.','varchar(max)')
,1,1,'')
from t
group by sl, next, status, day
)
select
sl
, next
, status
, daylist = stuff((
select
char(10)+convert(varchar(10),day)+'-'+i.daylist
from cte as i
where cte.status = i.status
and cte.next = i.next
order by i.day
for xml path (''), type).value('.','varchar(max)')
,1,1,'')
from cte
group by sl, next, status
order by next, status desc
rextester演示:http://rextester.com/FQE41002
返回:
+----+------+--------+-----------+
| sl | next | status | daylist |
+----+------+--------+-----------+
| A | 1 | Yes | 1-1,2,3,4 |
| | | | 2-1,3,4 |
| A | 1 | No | 2-2 |
| A | 2 | Yes | 1-1,2,3,4 |
+----+------+--------+-----------+
答案 1 :(得分:1)
Declare @YourTable table (sl varchar(10),next int,day int,count int, status varchar(10))
Insert Into @YourTable values
('A' ,1 ,1 ,1 ,'Yes'),
('A' ,1 ,1 ,2 ,'Yes'),
('A' ,1 ,1 ,3 ,'Yes'),
('A' ,1 ,1 ,4 ,'Yes'),
('A' ,1 ,2 ,1 ,'Yes'),
('A' ,1 ,2 ,2 ,'No'),
('A' ,1 ,2 ,3 ,'Yes'),
('A' ,1 ,2 ,4 ,'Yes'),
('A' ,2 ,1 ,1 ,'Yes'),
('A' ,2 ,1 ,2 ,'Yes'),
('A' ,2 ,1 ,3 ,'Yes'),
('A' ,2 ,1 ,4 ,'Yes')
Select sl = IIF(Lag(concat(sl,next,status),1) over (Order by RN)=concat(sl,next,status),'',sl)
,next = IIF(Lag(concat(sl,next,status),1) over (Order by RN)=concat(sl,next,status),'',cast(next as varchar(25)))
,status = IIF(Lag(status,1) over (Order by RN)=status,'',status)
,daylist = concat(day,'-',iif(rowCnt=maxRow,'All',string))
From (
Select *,RN = Row_Number() over (Order by sl,next,day,status desc)
From (
Select sl,Next,Status,Day,rowCnt=count(*)
From @YourTable
Group By sl,Next,Status,Day
) A
Cross Apply (Select maxRow=count(*) From @YourTable Where sl=A.sl and next=A.next and day=A.day ) C
Cross Apply (
Select String = Stuff((Select ',' +cast(count as varchar(25))
From @YourTable
Where sl=A.sl and next=A.next and day=A.day and status=A.status
For XML Path ('')),1,1,'')
) B
) A
Order By RN
返回
sl next status daylist
A 1 Yes 1-All
2-1,3,4
A 1 No 2-2
A 2 Yes 1-All
答案 2 :(得分:0)
DECLARE @tb TABLE(sl VARCHAR(2),[next] INT,[day] INT ,[count] INT,status VARCHAR(3))
INSERT INTO @tb
SELECT 'A',1,1,1,'Yes' UNION ALL
SELECT 'A',1,1,2,'Yes' UNION ALL
SELECT 'A',1,1,3,'Yes' UNION ALL
SELECT 'A',1,1,4,'Yes' UNION ALL
SELECT 'A',1,2,1,'Yes' UNION ALL
SELECT 'A',1,2,2,'No' UNION ALL
SELECT 'A',1,2,3,'Yes' UNION ALL
SELECT 'A',1,2,4,'Yes' UNION ALL
SELECT 'A',2,1,1,'Yes' UNION ALL
SELECT 'A',2,1,2,'Yes' UNION ALL
SELECT 'A',2,1,3,'Yes' UNION ALL
SELECT 'A',2,1,4,'Yes'
SELECT sl,[next],[status] ,LTRIM(t.[day])+'-'+STUFF(c.s,1,1,'') AS daylist
FROM @tb AS t
CROSS APPLY(
SELECT CASE WHEN a.OtherStatusCnt>0 THEN
CASE WHEN a.[status]=t.[status] THEN ','+LTRIM(a.[count]) ELSE '' END
ELSE
CASE WHEN a.id=1 THEN '.All' ELSE '' END
END
FROM (
SELECT tt.count,tt.[status]
,COUNT(CASE WHEN tt.[status]!=t.[status] THEN 1 ELSE NULL END)OVER() AS OtherStatusCnt
,ROW_NUMBER()OVER(ORDER BY tt.[count]) AS id
FROM @tb AS tt WHERE tt.sl=t.sl AND tt.[next]=t.[next] AND tt.[day]=t.[day]
) AS a
FOR XML PATH('')
) c(s)
GROUP BY sl,[next],[day],[status],c.s
ORDER BY sl,[next],[status] desc
sl next status daylist ---- ----------- ------ --------- A 1 Yes 1-All A 1 Yes 2-1,3,4 A 1 No 2-2 A 2 Yes 1-All