在新列中显示行数据(透视?)

Posted

技术标签:

【中文标题】在新列中显示行数据(透视?)【英文标题】:Display row data in new columns (pivot?) 【发布时间】:2021-01-18 18:56:48 【问题描述】:

我目前正在处理一个非常简单的查询,它会提取过去 3 年内访问过某个地点的人的列表。我的问题是,在这 3 年的时间段内,有很多人多次访问过,所以这些人有多行归因于他们。我想要做的是获取一个字段,例如他们的访问日期并将其显示在一个列中,为每个额外的访问日期添加列,以便所有给定人员的数据都显示在一行中。在进行一些调查后,听起来我正在寻找一个枢轴函数,但我在弄清楚如何将它应用于我的具体情况时遇到了一些麻烦。

这是我的查询:

SELECT DISTINCT
d.PersonID,
d.DOB,
d.Age as [Current Age],
DATEDIFF(YY,d.DOB,v.VisitDate) -                                        
   CASE                                                                                             
       WHEN DATEADD(YY,DATEDIFF(YY,d.DOB,v.VisitDate),d.DOB)   
       > v.VisitDate THEN 1                                                                         
    ELSE 0                                                                                          
   END AS [Age at Visit],
v.VisitDate

FROM Demographic d JOIN Visit v ON d.PersonID = v.PersonID

WHERE VisitDate BETWEEN '01/01/2017' AND '12/31/2020'

当然,按照目前的编写方式,我最终会得到这样的结果,每个访问者都有多行:

PersonID    ...    VisitDate
---------------------------------
1001        ...    04/06/2018
1001        ...    10/19/2019
1002        ...    07/20/2019
1003        ...    11/17/2017
1003        ...    02/01/2019
1003        ...    08/11/2020

这就是我想要的样子。我意识到这并没有考虑到我的访问年龄计算,但如果这意味着让这项工作发挥作用,我可能会继续并摆脱它:

PersonID    ...    VisitDate1    VisitDate2    VisitDate3
------------------------------------------------------------
1001        ...    04/06/2018    10/19/2019
1002        ...    07/20/2019
1003        ...    11/17/2017    02/01/2019    08/11/2020

根据我对这些数据的了解,任何给定的人应该在此时间范围内最多只有 4 次访问,但是有没有办法自动添加额外的列,以防万一有人超过4?

【问题讨论】:

每人最多访问 3 次吗? 每人最多应该只有 4 个(2017、2018、2019 和 2020 年可能有一个),但可能会有一些异常 可能有一些异常 = 动态枢轴 【参考方案1】:

看看下面是否适合你...动态添加更多的 4 次访问可以通过使用动态 sql 来实现

CREATE TABLE #T (
ID int,
Visit Date
)
GO


INSERT #T
SELECT 1001, '04/06/2018' UNION
SELECT 1001, '10/19/2019' UNION
SELECT 1002, '07/20/2019' UNION
SELECT 1003, '11/17/2017' UNION
SELECT 1003, '02/01/2019' UNION
SELECT 1003, '08/11/2020' 
GO

SELECT * 
FROM 
(
    SELECT * 
        , CONCAT('Visit', ROW_NUMBER() OVER(PARTITION BY ID ORDER BY Visit)) AS Visit_Cnt
    FROM #T
) X
PIVOT
(
    MAX(Visit) FOR Visit_Cnt IN([Visit1], [Visit2], [Visit3], [Visit4])
) A

【讨论】:

以上是关于在新列中显示行数据(透视?)的主要内容,如果未能解决你的问题,请参考以下文章

SQL:添加行值并显示在新列中

Excle数据透视如何创建多条件汇总的数据透视表

从行创建/透视列并创建透视后,我想在 SQL 中新创建的列中添加不同列的值

多索引数据框到带有新列的数据透视表

根据列中的一组查找最大值行并在熊猫中进行透视

使用 pandas 数据框列值来透视其他列