I have a large(ish) DB. Simply put customer records. Now I have two tables; one is CustomerInfo and PhoneNumbers. Some sample data would be,
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
Now as you could see, Paul and Francis have just one number, but Eugin has two. In a normal world, if I join the two tables as,
SELECT
c.CustName,
p.PhoneNumber
FROM
CustomerInfo c
JOIN
PhoneNumbers p
ON c.CustID = p.CustID
I would get,
CustName | PhoneNumber
------------+--------------------
Paul | 0117123456
Eugin | 0120212345
Eugin | 0784256864
Francis | 0204587895
This is right, but I am running another Query that need the result to be,
CustName | PhoneNumber1 | PhoneNumber2
------------+-------------------+---------------
Paul | 0117123456 | NULL
Eugin | 0120212345 | 0784256864
Francis | 0204587895 | NULL
I could write a table variable from a function. But as this is going to be part of a Query, I was hoping if there were any other solution.
EDIT - I would like to highlight the section, as this is going to be part of a Query, I was hoping if there were any other solution, The actual query is going to be,
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
What I would like is,
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
You can use ROW_NUMBER() to give each phone number a rank within its customer ID, then use this to PIVOT the data:
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;
If you have an unknown number of phone numbers and want to include them all where applicable, I would be inclined to use a single column and display a comma delimited list, which you can do using SQL Server's XML extensions. This is easier than using dynamic SQL, and also easier for anything dealing with the results as you have a known number of columns being returned:
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With