使用 SQL 查询对新列进行分组和扩展?
Posted
技术标签:
【中文标题】使用 SQL 查询对新列进行分组和扩展?【英文标题】:Group and expand to new columns using a SQL query? 【发布时间】:2021-06-25 07:38:41 【问题描述】:拥有这些数据:
Name | Date |
---|---|
John | 2021-03-01 10:00 |
Paul | 2021-03-01 11:00 |
Paul | 2021-03-01 14:20 |
John | 2021-03-01 15:00 |
Paul | 2021-03-01 17:00 |
如何获得此结果(按 ASC 排序的日期)
Name | Date1 | Date2 | Date2 |
---|---|---|---|
John | 2021-03-01 10:00 | 2021-03-01 15:00 | NULL |
Paul | 2021-03-01 11:00 | 2021-03-01 14:20 | 2021-03-01 17:00 |
谢谢。
【问题讨论】:
这能回答你的问题吗? Group by column and multiple Rows into One Row multiple columns如果没有,为什么不呢? 可能。我搜索但没有找到那个问题/答案。谢谢。 你使用的是哪个版本的sql server? 我安装了 SQL Server 2014 和 2017 【参考方案1】:如果您想让您的查询动态化,这意味着无论您对任何给定名称有多少个日期,此查询都会自动生成该数量的列,请尝试以下查询:
架构:
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);
输出:
Name Date1 Date2 Date3 John 2021-03-01 10:00:00.000 2021-03-01 15:00:00.000 null Paul 2021-03-01 11:00:00.000 2021-03-01 14:20:00.000 2021-03-01 17:00:00.000
db小提琴here
【讨论】:
这也很有用。谢谢 不客气。但是,如果日期数是固定的,那么您的查询将比这个运行得快得多。 感谢您的提问。这是一个不错的。最良好的祝愿。【参考方案2】:在 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
【讨论】:
【参考方案3】:我尝试过使用 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 查询对新列进行分组和扩展?的主要内容,如果未能解决你的问题,请参考以下文章