|
Posted by Erland Sommarskog on 12/30/06 16:48
John Bell (jbellnewsposts@hotmail.com) writes:
> But,I want a query which shows the results in a way below:
> (id,Name,tellephone,mobile,Fax,e-mail,address,comment)
> (4,nassa,071163738,091463738,Null,Null,XXX,Null)
>
>
> SELECT b.id, b.name, n1.telno AS [Tellphone], n2.telno AS [Mobile],
> n3.telno AS [Fax], b.address, b.comment
> FROM Telbook b
> LEFT JOIN ( TelNumbers n1
> JOIN Teltypes t1 ON t1.fk = n1.telNotype AND t1.teltypes = 'Tellphone' )
> on n1.telbookid = b.id
> LEFT JOIN ( TelNumbers n2
> JOIN Teltypes t2 ON t2.fk = n2.telNotype AND t2.teltypes = 'Mobile' ) on
> n2.telbookid = b.id
> LEFT JOIN ( TelNumbers n3
> JOIN Teltypes t3 ON t3.fk = n3.telNotype AND t3.teltypes = 'Fax' ) on
> n3.telbookid = b.id
John, here is a way to write that query with a single join:
SELECT b.id, b.Name, a.Tellphone, a.Mobile, a.Fax, b.address, b.comment
FROM Telbook b
JOIN (SELECT n.telbookid,
Tellphone = MAX(CASE WHEN t.teltypes = 'Tellphone'
THEN n.telno
END),
Mobile = MAX(CASE WHEN t.teltypes = 'Mobile'
THEN n.telno
END),
Fax = MAX(CASE WHEN t.teltypes = 'Fax'
THEN n.telno
END)
FROM TelNumbers n
JOIN Teltypes t ON n.telNotype = t.fk
GROUP BY n.telbookid) AS a ON a.telbookid = b.id
This is, in my opinion, *the* way to write a pivot query. It's uses
ANSI SQL, so it has a chance of being portable. And once you have learnt
the principle, it's easy to remember.
The trick is the use of MAX. Each CASE expression will return at most
one non-NULL value. So whether we use MAX or MIN does not matter
The syntax with the PIVOT keyword introduced in SQL 2005, on the other
hand, is useless in my opinion. The syntax is not any more compact than
the above, nor even any easier to use or remember. And top of that it's
propritary and not portable. Possibly, it helps the optimizer so a query
with PIVOT could execute faster than using CASE and GROUP BY. Personally,
I haven't even bothered to learn the PIVOT/UNPIVOT syntax.
Also, the PIVOT query you posted, will not work for Nassa because he/she
uses ntext which cannot be used with PIVOT. I see in your tables that
you use nvarchar(MAX), but I tried yesterday in
microsoft.public.sqlserver.programming to convince Nassa to use
nvarchar(MAX) instead, but he/she did not even comment on it.
--
Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se
Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx
[Back to original message]
|