sql-server 没有聚合函数ID作为列名的PIVOT

vybvopom  于 2022-10-31  发布在  其他
关注(0)|答案(2)|浏览(547)

我有一个疑问

SELECT a.Name, b.Date FROM
Table1 a 
JOIN Table2 b on a.deviceID=b.id
where a.date > '2022-10-01'

这给了我一个

Name Date
A1   '2022-10-01 12:13'
A2   '2022-10-02 14:15'
A2   '2022-10-02 15:16'
A5   '2022-10-03 16:19'

等等。
我想达到的结果是

A1                 A2                        A5 
'2022-10-01 12:13' '2022-10-02 14:15''2022-10-03 16:19' 
                    '2022-10-02 15:16'

最理想的结果是每天只接收一个日期。我可以使用Pivot来实现吗?

cczfrluj

cczfrluj1#

如果没有聚合,透视就不能完成(在T-SQL中)。至于你想要达到什么,似乎你需要对PIVOT的值进行Name/条件聚合,并对ROW_NUMBER的值进行分组。
我个人更喜欢使用条件聚合而不是限制性的PIVOT操作符,但我已经包含了这两种操作符的示例:

USE Sandbox;
GO

CREATE TABLE #YourData (Name char(2),
                        Date datetime2(0));
GO
INSERT INTO #YourData (Name,
                       Date)
VALUES('A1','2022-10-01T12:13:00'),
      ('A2','2022-10-02T14:15:00'),
      ('A2','2022-10-02T15:16:00'),
      ('A5','2022-10-03T16:19:00');
GO

WITH RNs AS(
    SELECT [Name],
           [Date],
           ROW_NUMBER() OVER (PARTITION BY [Name] ORDER BY [Date]) AS RN
    FROM #YourData)
SELECT MAX(CASE [Name] WHEN 'A1' THEN [Date] END) AS A1,
       MAX(CASE [Name] WHEN 'A2' THEN [Date] END) AS A2,
       MAX(CASE [Name] WHEN 'A5' THEN [Date] END) AS A5
FROM RNs
GROUP BY RN;
GO

SELECT P.A1,
       P.A2,
       P.A5
FROM (SELECT [Name],
             [Date],
             ROW_NUMBER() OVER (PARTITION BY [Name] ORDER BY [Date]) AS RN
     FROM #YourData)YD
PIVOT(MAX([date])
      FOR [Name] IN (A1,A2,A5))P;

GO
DROP TABLE #YourData;
hjzp0vay

hjzp0vay2#

如果您想要枢纽分析,但要将所有相关值保留在相同字段中,而不是建立假列,您可以使用STRING_AGG。您可以使用CHAR(10)来取代“,”分隔符号,或使用HTML来新增分行符号。您不会在SSMS中看到它,但视前端而定,它会呈现两个项目,一个在另一个之下。

DROP TABLE IF EXISTS #YourData
CREATE TABLE #YourData (Name char(2),
                        Date datetime2(0));
GO
INSERT INTO #YourData (Name,
                       Date)
VALUES('A1','2022-10-01T12:13:00'),
      ('A2','2022-10-02T14:15:00'),
      ('A2','2022-10-02T15:16:00'),
      ('A5','2022-10-03T16:19:00');
GO

DECLARE @Seperator VARCHAR(10) = ' , '

SELECT 
 [A1] , [A2], [A3], [A4], [A5]
FROM  
(
  SELECT name, STRING_AGG(date,@Seperator) AS Dates
    FROM #YourData
    GROUP BY Name
) AS SourceTable  
PIVOT  
(  
  MAX(Dates)  
  FOR Name IN ([A1], [A2], [A3], [A4], [A5])  
) AS PivotTable;

相关问题