我有一个数据库,其中我有以下行:
ID | Date start | Date end
----------------------------------
a | 01-01-1950 | 30-01-1951
a | 01-01-1948 | 31-12-1949
a | 31-01-1951 | 01-06-2000
b | 01-01-1980 | 01-08-2010
c | 01-01-1990 | 31-12-2017
c | 31-01-1985 | 31-12-1989
我得到了什么
选择我想要返回以下内容的查询:
ID | Date start 1 | Date end 1 | Date start 2 | Date end 2 | Date start 3 | Date end 3
---------------------------------------------------------------------------------------------------
a | 01-01-1948 | 31-12-1949 | 01-01-1950 | 30-01-1951 | 31-01-1951 | 01-06-2000
b | 01-01-1980 | 01-08-2010
c | 31-01-1985 | 31-12-1989 | 01-01-1990 | 31-12-2017
我想要的是什么:
我能找到的大多数东西都希望它在同一列中,或者不希望它按时间顺序排序,所以不幸的是这些情况并不适用于我。
我现在真的知道如何解决这个问题。
答案 0 :(得分:4)
如果您只有三个日期,那么pivot
/条件聚合应该没问题:
select id,
max(case when seqnum = 1 then dstart end) as start_1,
max(case when seqnum = 1 then dend end) as end_1,
max(case when seqnum = 2 then dstart end) as start_2,
max(case when seqnum = 2 then dend end) as end_2,
max(case when seqnum = 3 then dstart end) as start_3,
max(case when seqnum = 3 then dend end) as end_3
from (select t.*,
row_number() over (partition by id order by dstart) as seqnum
from t
) t
group by id;
注意:您必须指定输出中的列数。如果你不知道有多少,你可以:
答案 1 :(得分:2)
答案 2 :(得分:0)
假设您有一个静态的日期范围,您可以使用窗口函数实现此目的...
;WITH cteData
(
ID,
DateStart,
DateEnd
)
AS
(
SELECT 'a', CONVERT(DATE, '01-01-1950'), CONVERT(DATE, '30-01-1951')
UNION ALL SELECT 'a', '01-01-1948', '31-12-1949'
UNION ALL SELECT 'a', '31-01-1951', '01-06-2000'
UNION ALL SELECT 'b', '01-01-1980', '01-08-2010'
UNION ALL SELECT 'c', '01-01-1990', '31-12-2017'
UNION ALL SELECT 'c', '31-01-1985', '31-12-1989'
),
cteDefineColumns
AS
(
SELECT RangeColumnID = ROW_NUMBER() OVER (PARTITION BY ID ORDER BY DateStart),
*
FROM cteData
)
SELECT col1.ID,
[Date start 1] = col1.DateStart,
[Date end 1] = col1.DateEnd,
[Date start 2] = col2.DateStart,
[Date end 2] = col2.DateEnd,
[Date start 3] = col3.DateStart,
[Date end 3] = col3.DateEnd
FROM cteDefineColumns AS col1
LEFT OUTER JOIN cteDefineColumns AS col2
ON col1.ID = col2.ID
AND col2.RangeColumnID = 2
LEFT OUTER JOIN cteDefineColumns AS col3
ON col1.ID = col3.ID
AND col3.RangeColumnID = 3
WHERE col1.RangeColumnID = 1
ORDER BY col1.ID,
col1.DateStart,
col1.DateEnd;
答案 3 :(得分:0)
我不确定你为什么要这样做,因为这个结构不太好。
if object_Id('tempdb..#TmpRankedTable') is not null drop table #TmpRankedTable
select Id, strt_dt, end_dt, row_number() over(partition by Id order by strt_dt) OrbyCol
into #TmpRankedTable
from dbo.YourTable
if object_Id('tempdb..#TmpStarts') is not null drop table #TmpStarts
select *
into #TmpStarts
from (
select Id, strt_dt, OrbyCol
from #TmpRankedTable) t
pivot (min(strt_dt) for OrbyCol in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10])) p
if object_Id('tempdb..#TmpEnds') is not null drop table #TmpEnds
select *
into #TmpEnds
from (
select Id, end_dt, OrbyCol
from #TmpRankedTable) t
pivot (min(end_dt) for OrbyCol in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10])) p
select
s.Id,
s.[1] [Start 1],
e.[1] [End 1],
s.[2] [Start 2],
e.[2] [End 2],
s.[3] [Start 3],
e.[3] [End 3],
s.[4] [Start 4],
e.[4] [End 4],
s.[5] [Start 5],
e.[5] [End 5],
s.[6] [Start 6],
e.[6] [End 6],
s.[7] [Start 7],
e.[7] [End 7],
s.[8] [Start 8],
e.[8] [End 8],
s.[9] [Start 9],
e.[9] [End 9],
s.[10] [Start 10],
e.[10] [End 10]
from #TmpStarts s
inner join #TmpEnds e on s.Id = e.Id
答案 4 :(得分:0)
您可以使用pivot来转置和查询,如下所示:
;with cte as (
select *, RowN = row_number() over(partition by id order by datestart) from #temp )
, cte2 as (
select id, [1] as [datestart1], [2] as [datestart2], [3] as datestart3 from
(select id, datestart, RowN from cte) sourcetable
pivot (max(datestart) for RowN in ([1],[2],[3]) ) p
)
, cte3 as (
select id, [1] as [dateend1], [2] as [dateend2], [3] as dateend3 from
(select id, dateend, RowN from cte) sourcetable
pivot (max(dateend) for RowN in ([1],[2],[3]) ) p
) select c2.id, c2.datestart1,c3.dateend1,c2.datestart2,c3.dateend2,c2.datestart3,c3.dateend3
from cte2 c2 left join cte3 c3 on c2.id = c3.id
如果您有动态列,则可以使用stuff创建动态查询以创建列列表并将此查询作为动态查询运行以获取所有列列表