使用SQL查询分组并展开到新列?
拥有这些数据: 名称 日期 约翰 2021-03-01 10:00 保罗 2021-03-01 11:00 保罗 2021-03-01 14:20 约翰 2021-03-01 15:00 保罗 2021-03-01 17:00使用SQL查询分组并展开到新列?,sql,sql-server,tsql,group-by,Sql,Sql Server,Tsql,Group By,拥有这些数据: 名称 日期 约翰 2021-03-01 10:00 保罗 2021-03-01 11:00 保罗 2021-03-01 14:20 约翰 2021-03-01 15:00 保罗 2021-03-01 17:00 基于Larnu的帮助,这起到了作用: WITH RNs AS( SELECT [Name], [DateTime], ROW_NUMBER() OVER (PARTITION BY Name ORDER B
基于Larnu的帮助,这起到了作用:
WITH RNs AS(
SELECT [Name],
[DateTime],
ROW_NUMBER() OVER (PARTITION BY Name ORDER BY (SELECT NULL)) AS RN
FROM dbo.Punch
WHERE Date = '2016-04-18'
)
SELECT Name,
MAX(CASE RN WHEN 1 THEN [DateTime] END) AS Result1,
MAX(CASE RN WHEN 2 THEN [DateTime] END) AS Result2,
MAX(CASE RN WHEN 3 THEN [DateTime] END) AS Result3,
MAX(CASE RN WHEN 4 THEN [DateTime] END) AS Result4
FROM RNs R
GROUP BY Name
基于Larnu的帮助,这起到了作用:
WITH RNs AS(
SELECT [Name],
[DateTime],
ROW_NUMBER() OVER (PARTITION BY Name ORDER BY (SELECT NULL)) AS RN
FROM dbo.Punch
WHERE Date = '2016-04-18'
)
SELECT Name,
MAX(CASE RN WHEN 1 THEN [DateTime] END) AS Result1,
MAX(CASE RN WHEN 2 THEN [DateTime] END) AS Result2,
MAX(CASE RN WHEN 3 THEN [DateTime] END) AS Result3,
MAX(CASE RN WHEN 4 THEN [DateTime] END) AS Result4
FROM RNs R
GROUP BY Name
如果您想使查询动态化,这意味着无论您对任何给定名称有多少个日期,此查询都将自动生成相应数量的列,请尝试以下查询: 模式:
create table mytable (Name varchar(50),[Date] Datetime);
insert into mytable values('John' , '2021-03-01 10:00');
insert into mytable values('Paul' , '2021-03-01 11:00');
insert into mytable values('Paul' , '2021-03-01 14:20');
insert into mytable values('John' , '2021-03-01 15:00');
insert into mytable values('Paul' , '2021-03-01 17:00');
查询:
declare @cols as varchar(max), @colsForSelect as varchar(max), @query as varchar(max);
select @colsForSelect=string_agg(concat(quotename(rn),' ', datename),',' )from(
select distinct concat('Date',rn) datename,rn from
(SELECT row_number()over(partition by name order by [date])rn from mytable)t)a
select @cols =string_agg(quotename(rn),',') from (
select distinct rn from
(SELECT row_number()over(partition by name order by [date])rn from mytable)t)a
set @query = 'Select Name, ' + @colsForSelect + ' from
(
SELECT *,row_number()over(partition by name order by [date])rn
from mytable
) x
pivot
(
max([date])
for rn in (' + @cols + ')
) p
group by Name,' + @cols
execute(@query);
输出:
名称
日期1
日期2
日期3
约翰
2021-03-01 10:00:00.000
2021-03-01 15:00:00.000
无效的
保罗
2021-03-01 11:00:00.000
2021-03-01 14:20:00.000
2021-03-01 17:00:00.000
如果您想使查询动态化,这意味着无论您对任何给定名称有多少个日期,此查询都将自动生成相应数量的列,请尝试以下查询: 模式:
create table mytable (Name varchar(50),[Date] Datetime);
insert into mytable values('John' , '2021-03-01 10:00');
insert into mytable values('Paul' , '2021-03-01 11:00');
insert into mytable values('Paul' , '2021-03-01 14:20');
insert into mytable values('John' , '2021-03-01 15:00');
insert into mytable values('Paul' , '2021-03-01 17:00');
查询:
declare @cols as varchar(max), @colsForSelect as varchar(max), @query as varchar(max);
select @colsForSelect=string_agg(concat(quotename(rn),' ', datename),',' )from(
select distinct concat('Date',rn) datename,rn from
(SELECT row_number()over(partition by name order by [date])rn from mytable)t)a
select @cols =string_agg(quotename(rn),',') from (
select distinct rn from
(SELECT row_number()over(partition by name order by [date])rn from mytable)t)a
set @query = 'Select Name, ' + @colsForSelect + ' from
(
SELECT *,row_number()over(partition by name order by [date])rn
from mytable
) x
pivot
(
max([date])
for rn in (' + @cols + ')
) p
group by Name,' + @cols
execute(@query);
输出:
名称
日期1
日期2
日期3
约翰
2021-03-01 10:00:00.000
2021-03-01 15:00:00.000
无效的
保罗
2021-03-01 11:00:00.000
2021-03-01 14:20:00.000
2021-03-01 17:00:00.000
我尝试了Stuff函数,而不是2017年服务器上引入的sting_agg。如果您使用的是2017年以下版本,则可以使用以下查询
declare @column_name varchar(5000)
declare @col_name varchar(5000)
set @column_name = (select stuff((select ','+'['+cast(rn as varchar(1000))+']' from(select distinct row_number()over(partition by name order by (select null))as rn from mytable)a
for xml path('')), 1,1,''))
set @col_name = (select stuff((select ','+'['+cast(rn as varchar(1000))+']' +' Date'+cast(rn as varchar(1000)) from(select distinct row_number()over(partition by name order by (select null))as rn from mytable)a
for xml path('')), 1,1,''))
exec('select name, '+@col_name +'
from (
select row_number()over(partition by name order by (select null))rn, year([date]) yr, *
from mytable
)a
pivot
(
max([date]) for [rn] in ('+@column_name+' )
)pv')
我尝试了Stuff函数,而不是2017年服务器上引入的sting_agg。如果您使用的是2017年以下版本,则可以使用以下查询
declare @column_name varchar(5000)
declare @col_name varchar(5000)
set @column_name = (select stuff((select ','+'['+cast(rn as varchar(1000))+']' from(select distinct row_number()over(partition by name order by (select null))as rn from mytable)a
for xml path('')), 1,1,''))
set @col_name = (select stuff((select ','+'['+cast(rn as varchar(1000))+']' +' Date'+cast(rn as varchar(1000)) from(select distinct row_number()over(partition by name order by (select null))as rn from mytable)a
for xml path('')), 1,1,''))
exec('select name, '+@col_name +'
from (
select row_number()over(partition by name order by (select null))rn, year([date]) yr, *
from mytable
)a
pivot
(
max([date]) for [rn] in ('+@column_name+' )
)pv')
这回答了你的问题吗?如果没有,为什么不呢?可能吧。我搜索了一下,但没有找到那个问题/答案。谢谢。您使用的是哪个版本的sql server?我已经安装了sql server 2014和2017。这是否回答了您的问题?如果没有,为什么不呢?可能吧。我搜索了一下,但没有找到那个问题/答案。谢谢。您使用的是哪一版本的sql server?我已经安装了sql server 2014和2017,运行良好。祝你一切顺利。最好的祝愿。这也很有用。谢谢,非常欢迎。但如果日期的数目是固定的,那么您的查询将比这个查询运行得快得多。谢谢您的提问。这是一个很好的例子。最好的祝愿。这也很有用。谢谢,非常欢迎。但如果日期的数目是固定的,那么您的查询将比这个查询运行得快得多。谢谢您的提问。这是一个很好的例子。最美好的祝福。