sql-server - 在 SQL Server 中为每条记录创建行到列

标签 sql-server sql-server-2012

我有一个大(大概)数据库。简单说一下客户记录。现在我有两张 table ;一个是 CustomerInfoPhoneNumbers。一些样本数据是,

CustomerInfo
`````````````
CustID  |   CustName    |   CustomerLocation
--------+---------------+--------------------
1       |   Paul        |   Bristol
2       |   Eugin       |   Bournemouth
3       |   Francis     |   London

PhoneNumbers
````````````
PhoneID |   CustID  |   PhoneNumber
--------+-----------+----------------
1       |   1       |   0117123456
2       |   2       |   0120212345
3       |   2       |   0784256864
4       |   3       |   0204587895

现在您可以看到,PaulFrancis 只有一个号码,但 Eugin 有两个号码。在正常情况下,如果我将两个表连接为,

SELECT
    c.CustName,
    p.PhoneNumber
FROM
    CustomerInfo c
    JOIN 
    PhoneNumbers p
    ON c.CustID = p.CustID

我会得到,

CustName    |   PhoneNumber
------------+--------------------
Paul        |   0117123456
Eugin       |   0120212345
Eugin       |   0784256864
Francis     |   0204587895

这是对的,但我正在运行另一个需要结果的查询,

CustName    |   PhoneNumber1    |   PhoneNumber2
------------+-------------------+---------------
Paul        |   0117123456      |   NULL
Eugin       |   0120212345      |   0784256864
Francis     |   0204587895      |   NULL

我可以从一个函数中编写一个表变量。但由于这将成为查询的一部分,我希望是否还有其他解决方案。

编辑 - 我想突出显示该部分,因为这将成为查询的一部分,我希望是否还有其他解决方案,实际查询将是,

SELECT 
    per.[PersonId],
    per.[ClientReference],
    sal.SalutationName,
    per.[FirstName],
    per.[LastName],
    per.[DateOfBirth],
    per.[Password]
FROM 
    [Customers].[people].[Person] per
    JOIN 
    [Customers].[people].[Salutation] sal
    ON sal.SalutationId = per.SalutationId

我想要的是,

SELECT 
    per.[PersonId],
    per.[ClientReference],
    sal.SalutationName,
    per.[FirstName],
    per.[LastName],
    per.[DateOfBirth],
    per.[Password],
    pn.[PhoneNumber1], --Made up column, there is only one column in the pn table
    pn.[PhoneNumber2]  --Made up column, there is only one column in the pn table
FROM 
    [Customers].[people].[Person] per
    JOIN 
    [Customers].[people].[Salutation] sal
    ON sal.SalutationId = per.SalutationId
    JOIN 
    [Customers].[comms].[PhoneNumber] pn
    ON per.PersonId = pn.PersonId

最佳答案

您可以使用 ROW_NUMBER()给每个电话号码在其客户 ID 中的排名,然后将其用于 PIVOT数据:

SELECT  CustID,
        PhoneNumber1 = pvt.[1],
        PhoneNumber2 = pvt.[2],
        PhoneNumber3 = pvt.[3],
        PhoneNumber4 = pvt.[4]
FROM    (   SELECT  CustID, 
                    PhoneNumber,
                    RowNum = ROW_NUMBER() OVER(PARTITION BY CustID ORDER BY Phonenumber)
            FROM    PhoneNumbers 
        ) AS pn
        PIVOT 
        (   MAX(Phonenumber)
            FOR RowNum IN ([1], [2], [3], [4]) -- INCREASE/DECREASE COLUMNS AS REQUIRED
        ) AS pvt;

如果您有未知数量的电话号码并希望在适用的情况下包括所有电话号码,我倾向于使用单列并显示逗号分隔列表,您可以使用 SQL Server's XML extensions 来做到这一点。 .这比使用动态 SQL 更容易,而且对于处理结果的任何事情也更容易,因为您有已知数量的返回列:

SELECT  c.CustID,
        c.CustName,
        c.CustomerLocation,
        PhoneNumbers = STUFF((  SELECT  ',' + p.PhoneNumber
                                FROM    PhoneNumbers AS p
                                WHERE   p.CustID = c.CustID
                                FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 1, '')
FROM    CustomerInfo  AS c;

关于sql-server - 在 SQL Server 中为每条记录创建行到列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30801923/

相关文章:

sql-server - 如何停止EF4.1 Code-First为实体PK创建Culstered索引

sql - 确定列是增加还是减少

c# - 如何使用此 linq 查询获取驱动程序 ID 列

sql - 无法在存储过程中调用存储过程

sql - SQL Server Express LocalDB 可以远程连接吗?

sql-server - 将数据插入 SQL Server 中的表时出错

sql - 子查询返回超过 1 个值。当子查询后面有 =、!= 等时,这是不允许的

sql-server - 在存在语句中使用表变量

sql-server - 获取表中每个唯一列值的最大记录