在 SQL Server 2008 中将行转换为列

Convert rows to columns in SQL Server 2008

我们有一个 table 叫做 Licenses。这是它的样子:

CustNum LicenseAddress License ExpiryDate
155 123 Y32CA 12/31/2018
155 998 Y32CB 12/31/2020
155 568 Y32CC 12/31/2022

这是我想要的样子:

LicAddr1 Lic1 ExpiryDate1 LicAddr2 Lic2 ExpiryDate2 LicAddr3 Lic3 ExpiryDate3
123 Y32CA 12/31/2018 998 Y32CB 12/31/2020 568 Y32CC 12/31/2022

这是我目前的查询,但它只返回 NULL:

SELECT LicAddr1, 
       Lic1,
       ExpiryDate1,
       LicAddr2,
       Lic2,
       ExpiryDate2,
       LicAddr3,
       Lic3,
       ExpiryDate3
FROM (SELECT CustNum, LicenseAddress, License, ExpiryDate FROM Licenses) d
PIVOT (
       MAX(ExpiryDate) 
       FOR CustNum IN (LicAddr1, Lic1, ExpiryDate1, LicAddr2, Lic2, ExpiryDate2, LicAddr3, Lic3, ExpiryDate3) 
      ) piv

我做错了什么?

PIVOT 并不是你真正想要的,特别是因为你试图从每一行中获取多个值(这对聚合 PIVOT 尝试不太有效提供)。

我在这里假设您想要最新的三个许可证,在这种情况下,我们可以为每个 CustNum 应用一个行号,按 ExpiryDate 排序(最新的在前),然后翻转它们他们是 left-to-right oldest-to-newest:

;WITH cte AS
(
  SELECT CustNum, LicenseAddress, License, ExpiryDate,
    rn = ROW_NUMBER() OVER (PARTITION BY CustNum ORDER BY ExpiryDate DESC)
  FROM dbo.Licenses
)
SELECT CustNum,
  LicAddr1    = MAX(CASE WHEN rn = 3 THEN LicenseAddress END),
  Lic1        = MAX(CASE WHEN rn = 3 THEN License        END),
  ExpiryDate1 = MAX(CASE WHEN rn = 3 THEN ExpiryDate     END),
  LicAddr2    = MAX(CASE WHEN rn = 2 THEN LicenseAddress END),
  Lic2        = MAX(CASE WHEN rn = 2 THEN License        END),
  ExpiryDate2 = MAX(CASE WHEN rn = 2 THEN ExpiryDate     END),
  LicAddr3    = MAX(CASE WHEN rn = 1 THEN LicenseAddress END),
  Lic3        = MAX(CASE WHEN rn = 1 THEN License        END),
  ExpiryDate3 = MAX(CASE WHEN rn = 1 THEN ExpiryDate     END)
FROM cte
GROUP BY CustNum;

结果:

CustNum LicAddr1 Lic1 ExpiryDate1 LicAddr2 Lic2 ExpiryDate2 LicAddr3 Lic3 ExpiryDate3
155 123 Y32CA 2018-12-31 998 Y32CB 2020-12-31 568 Y32CC 2022-12-31