Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
DB Engine
SQL ServerMSDESQL Server CE
Services
Analysis (Data Mining)Analysis (OLAP)DTSIntegration ServicesNotification ServicesReporting Services
Programming
CLRConnectivitySQLXML
Other Technologies
ClusteringEnglish QueryFull-Text SearchReplicationService Broker
General
Data WarehousingPerformanceSecuritySetupSQL Server ToolsOther SQL Server Topics
DirectoryUser Groups
Related Topics
MS AccessOther DB ProductsMS Server Products.NET DevelopmentVB DevelopmentJava DevelopmentMore Topics ...

SQL Server Forum / General / Other SQL Server Topics / December 2006

Tip: Looking for answers? Try searching our database.

PIVOT

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Nassa - 30 Dec 2006 06:22 GMT
Hi everyone,

I have 3 tables:
Telbook(Id:int,Name:char,address:char,comment:ntext,owneruserid:int),
PK:id
TelNumbers(telbookid:int,telno:char,telNotype:int,syscode:int),PK:syscode,F­K:telNumbers.telbookid=telbook.id

Teltypes(teltypes:char,fk:int),FK:telnumbers.telnotype=teltypes.fk

The question is here that I can create a query which results are:
(id,Name,telno,telnotype,teltypes,address,comment)
(4,nassa,091463738,2,Mobile,XXX,Null)
(4,nassa,071163738,1,Tellphone,XXX,Nul)

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)

I run SQL server 2005, and I want to use PIVOT but I dnt know how!.

Thanks,
Nassa
John Bell - 30 Dec 2006 10:38 GMT
Hi everyone,

I have 3 tables:
Telbook(Id:int,Name:char,address:char,comment:ntext,owneruserid:int),
PK:id
TelNumbers(telbookid:int,telno:char,telNotype:int,syscode:int),PK:syscode,F­K:telNumbers.telbookid=telbook.id

Teltypes(teltypes:char,fk:int),FK:telnumbers.telnotype=teltypes.fk

The question is here that I can create a query which results are:
(id,Name,telno,telnotype,teltypes,address,comment)
(4,nassa,091463738,2,Mobile,XXX,Null)
(4,nassa,071163738,1,Tellphone,XXX,Nul)

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)

I run SQL server 2005, and I want to use PIVOT but I dnt know how!.

Thanks,
Nassa

Check out http://www.aspfaq.com/etiquette.asp?id=5006 on how to post DDL and
Sample data that is useful such as

CREATE TABLE Telbook(Id int not null constraint PK_telbook PRIMARY KEY,

[Name] varchar(20),

[address] varchar(60),

comment nvarchar(MAX),

owneruserid int)

CREATE TABLE Teltypes(teltypes varchar(30),

[fk] int not null constraint PK_Teltypes PRIMARY KEY)

CREATE TABLE TelNumbers(

telbookid int NOT NULL CONSTRAINT FK_TelNumbers_Telbook FOREIGN KEY
REFERENCES Telbook(id),

telno char(15),

telNotype int CONSTRAINT FK_TelNumbers_Teltypes FOREIGN KEY REFERENCES
Teltypes(fk),

syscode int not null CONSTRAINT PK_TelNumbers PRIMARY KEY)

INSERT INTO Teltypes(teltypes, [fk] )

SELECT 'Tellphone', 0

UNION ALL SELECT 'Mobile', 1

UNION ALL SELECT 'Fax', 2

INSERT INTO Telbook(Id, [Name], [address], comment, owneruserid)

SELECT 1, 'Fred', 'The Burrow', NULL, 1

UNION ALL SELECT 2, 'George', 'The Burrow', NULL, 2

UNION ALL SELECT 3, 'Ron', 'The Burrow', NULL, 3

UNION ALL SELECT 4, 'Ginny', 'The Burrow', NULL, 4

UNION ALL SELECT 5, 'Percy', 'The Burrow', NULL, 5

INSERT INTO TelNumbers(telbookid, telno, telNotype, syscode)

SELECT 1, '0921323123', 1, 1

UNION ALL SELECT 1, '0123323123', 0, 2

UNION ALL SELECT 2, '0123323123', 0, 3

UNION ALL SELECT 3, '0123323123', 0, 4

UNION ALL SELECT 4, '0123323123', 0, 5

UNION ALL SELECT 5, '0123323123', 0, 6

UNION ALL SELECT 2, '0944423123', 1, 7

UNION ALL SELECT 5, '0955423123', 1, 8

UNION ALL SELECT 5, '0123323125', 2, 9

It would have been useful to post the query you did have for:

The question is here that I can create a query which results are:
(id,Name,telno,telnotype,teltypes,address,comment)

Such as:

SELECT b.id, b.name, n.telno, n.telnotype, t.teltypes, b.address, b.comment

FROM Telbook b

JOIN TelNumbers n on n.telbookid = b.id

JOIN Teltypes t ON t.fk = n.telNotype

And for the following query, if you have set types you can self join instead
of using a Pivot such as

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

But if you do want to use a pivot try something like:

SELECT id, name, [Tellphone], [Mobile], [Fax], address, comment

FROM

( SELECT b.id, b.name, b.address, b.comment, t.teltypes, n.telno

FROM Telbook b

JOIN TelNumbers n on n.telbookid = b.id

JOIN Teltypes t ON t.fk = n.telNotype

) AS SourceTable

PIVOT

(

MAX(telno)

FOR teltypes IN ( [Tellphone], [Mobile], [Fax] )

) AS pvt

ORDER BY id

John
Erland Sommarskog - 30 Dec 2006 16:48 GMT
> But,I want a query which shows the results in a way below:
> (id,Name,tellephone,mobile,Fax,e-mail,address,comment)
[quoted text clipped - 12 lines]
> 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.

Signature

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

John Bell - 30 Dec 2006 17:08 GMT
Hi Erland

> 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.

I would hope that a lack of comment would not mean that Nassa was opposed to
using this new feature, which would probably be more benificial than using
PIVOT.

I would hope that the design was not restricted to a single number for a
given type of number e.g. multiple mobile numbers, which would show that all
the methods have their limitations.

Neither of us suggested doing this on the client, which is still probably
the best place to do this regardless of SQL Server's capability.

John
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.