在SQL Server中为每个记录创建行

Pau*_*cis 3 sql-server sql-server-2012

我有一个大的(ish)数据库.简单地把客户记录.现在我有两张桌子; 一个是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
Run Code Online (Sandbox Code Playgroud)

现在,你可以看到,Paul并且Francis只有一个数字,但Eugin有两个.在正常的世界中,如果我加入两个表格,

SELECT
    c.CustName,
    p.PhoneNumber
FROM
    CustomerInfo c
    JOIN 
    PhoneNumbers p
    ON c.CustID = p.CustID
Run Code Online (Sandbox Code Playgroud)

我会的,

CustName    |   PhoneNumber
------------+--------------------
Paul        |   0117123456
Eugin       |   0120212345
Eugin       |   0784256864
Francis     |   0204587895
Run Code Online (Sandbox Code Playgroud)

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

CustName    |   PhoneNumber1    |   PhoneNumber2
------------+-------------------+---------------
Paul        |   0117123456      |   NULL
Eugin       |   0120212345      |   0784256864
Francis     |   0204587895      |   NULL
Run Code Online (Sandbox Code Playgroud)

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

编辑 -我想强调一节,as this is going to be part of a Query, I was hoping if there were any other solution实际的查询将是,

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
Run Code Online (Sandbox Code Playgroud)

我想要的是,

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
Run Code Online (Sandbox Code Playgroud)

Gar*_*thD 5

您可以使用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;
Run Code Online (Sandbox Code Playgroud)

如果您有一个未知数量的电话号码,并希望将它们全部包含在适当的位置,我倾向于使用单个列并显示逗号分隔列表,您可以使用SQL Server的XML扩展来完成.这比使用动态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;
Run Code Online (Sandbox Code Playgroud)