Click here to monitor SSC
SQLServerCentral is supported by Red Gate Software Ltd.
 
Log in  ::  Register  ::  Not logged in
 
 
 
        
Home       Members    Calendar    Who's On


Add to briefcase ««12

Return 1 record with data from multiple tables Expand / Collapse
Author
Message
Posted Saturday, March 30, 2013 11:51 AM


SSC-Dedicated

SSC-DedicatedSSC-DedicatedSSC-DedicatedSSC-DedicatedSSC-DedicatedSSC-DedicatedSSC-DedicatedSSC-DedicatedSSC-DedicatedSSC-DedicatedSSC-DedicatedSSC-DedicatedSSC-Dedicated

Group: General Forum Members
Last Login: Today @ 11:25 PM
Points: 36,797, Visits: 31,259
umarrizwan (3/29/2013)
one easy solution, using xml path.




SELECT P.PRODUCTID,P.PRODUCTNAME,C.CategoryID,C.CATEGORYNAME,
STUFF((SELECT ',' + convert(varchar,PP.ProductQuantity)
FROM ProductPricing PP
WHERE PP.PRODUCTID=P.PRODUCTID
FOR XML PATH('')),1,1,'') AS ProductQuantity,
STUFF((SELECT ',' + convert(varchar,PP.ProductCost)
FROM ProductPricing PP
WHERE PP.PRODUCTID=P.PRODUCTID
FOR XML PATH('')),1,1,'') AS ProductCost
FROM PRODUCT P
JOIN Categories C ON C.CategoryID=P.CategoryID


Although that code works, it doesn't come close the the requested output.


--Jeff Moden
"RBAR is pronounced "ree-bar" and is a "Modenism" for "Row-By-Agonizing-Row".

First step towards the paradigm shift of writing Set Based code:
Stop thinking about what you want to do to a row... think, instead, of what you want to do to a column."

(play on words) "Just because you CAN do something in T-SQL, doesn't mean you SHOULDN'T." --22 Aug 2013

Helpful Links:
How to post code problems
How to post performance problems
Post #1437213
Posted Saturday, March 30, 2013 12:00 PM


SSC-Dedicated

SSC-DedicatedSSC-DedicatedSSC-DedicatedSSC-DedicatedSSC-DedicatedSSC-DedicatedSSC-DedicatedSSC-DedicatedSSC-DedicatedSSC-DedicatedSSC-DedicatedSSC-DedicatedSSC-Dedicated

Group: General Forum Members
Last Login: Today @ 11:25 PM
Points: 36,797, Visits: 31,259
vinu512 (3/28/2013)
This is how you can transform Mickey's query into a Dynamic Cross tab:

Declare @sql Varchar(MAX) 
-- Set up some test data
Create table product(ProductId Int, ProductName Varchar(30),CategoryID Int)
Create table category(CategoryID Int, CategoryName Varchar(30))
Create table productprices(ProductID Int, ProductQuantity Int, ProductCost Float)
Insert Into product
Select 1, 'Beer', 1
Union ALL
Select 2, 'Wine', 1
Union ALL
Select 3, 'Bourbon', 1
Union ALL
Select 4, 'Crisps', 2
Union ALL
Select 5, 'Nuts', 2
Insert Into category
Select 1,'Beverages'
Union ALL
Select 2,'Snacks'
Insert Into productprices
Select 1,1,2.00
Union ALL
Select 1,12,20.00
Union ALL
Select 1,24,36.00
Union ALL
Select 2,1,12.00
Union ALL
Select 2,6,60.00
Union ALL
Select 3,1,45.00
Union ALL
Select 4,10,12.00
Union ALL
Select 5,5,10.00
Union ALL
Select 5,10,16.00

-- Create query to dynamically pivot data
Select @sql = 'SELECT p.ProductID, p.ProductName, c.CategoryID, c.CategoryName, '
Select @sql = @sql + STUFF((Select DISTINCT ',MAX(CASE WHEN pp.Seq = ' + Cast(pp.Seq As Varchar) + ' THEN pp.ProductQuantity ELSE null END) As ProductQuantity' + Cast(pp.Seq As Varchar)
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY ProductQuantity) Seq, ProductID, ProductQuantity, ProductCost
FROM productprices
) pp FOR XML PATH('')),1,1,'') + ', '
Select @sql = @sql + STUFF((Select DISTINCT ',MAX(CASE WHEN pp.Seq = ' + Cast(pp.Seq As Varchar) + ' THEN pp.ProductCost ELSE null END) As ProductCost' + Cast(pp.Seq As Varchar)
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY ProductQuantity) Seq, ProductID, ProductQuantity, ProductCost
FROM productprices
) pp FOR XML PATH('')),1,1,'')
Select @sql = @sql + ' FROM product p
INNER JOIN category c ON p.CategoryID = c.CategoryID
INNER JOIN (
SELECT ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY ProductQuantity) Seq, ProductID, ProductQuantity, ProductCost
FROM productprices
) pp ON p.ProductId = pp.ProductID
GROUP BY p.ProductID, p.ProductName, c.CategoryID, c.CategoryName '
Execute(@sql)



Hope this helps.


Good example of a dynamic cross tab, Vinu. Can you change it to put output columns in the same order as requested?


--Jeff Moden
"RBAR is pronounced "ree-bar" and is a "Modenism" for "Row-By-Agonizing-Row".

First step towards the paradigm shift of writing Set Based code:
Stop thinking about what you want to do to a row... think, instead, of what you want to do to a column."

(play on words) "Just because you CAN do something in T-SQL, doesn't mean you SHOULDN'T." --22 Aug 2013

Helpful Links:
How to post code problems
How to post performance problems
Post #1437215
Posted Saturday, March 30, 2013 12:06 PM
SSC-Enthusiastic

SSC-EnthusiasticSSC-EnthusiasticSSC-EnthusiasticSSC-EnthusiasticSSC-EnthusiasticSSC-EnthusiasticSSC-EnthusiasticSSC-Enthusiastic

Group: General Forum Members
Last Login: Friday, May 9, 2014 11:34 AM
Points: 128, Visits: 489
Nice examples everyone, thanks!

Sean - I can only sell items individually and then in a second, pre-set quantity but that second quantity can differ between products. It could be 15 for Product A but 11 for Product B.

I've designed the table for quantities so that more can be added in the future. Although I don't see that happening, I didn't want to create a flat table design and find out in 6 months it's changing and I'd have to redesign my tables.

Mark



Post #1437216
Posted Monday, April 1, 2013 1:11 AM


Ten Centuries

Ten CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen Centuries

Group: General Forum Members
Last Login: Wednesday, July 23, 2014 8:48 AM
Points: 1,118, Visits: 1,582
Jeff Moden (3/30/2013)
vinu512 (3/28/2013)
This is how you can transform Mickey's query into a Dynamic Cross tab:

Declare @sql Varchar(MAX) 
-- Set up some test data
Create table product(ProductId Int, ProductName Varchar(30),CategoryID Int)
Create table category(CategoryID Int, CategoryName Varchar(30))
Create table productprices(ProductID Int, ProductQuantity Int, ProductCost Float)
Insert Into product
Select 1, 'Beer', 1
Union ALL
Select 2, 'Wine', 1
Union ALL
Select 3, 'Bourbon', 1
Union ALL
Select 4, 'Crisps', 2
Union ALL
Select 5, 'Nuts', 2
Insert Into category
Select 1,'Beverages'
Union ALL
Select 2,'Snacks'
Insert Into productprices
Select 1,1,2.00
Union ALL
Select 1,12,20.00
Union ALL
Select 1,24,36.00
Union ALL
Select 2,1,12.00
Union ALL
Select 2,6,60.00
Union ALL
Select 3,1,45.00
Union ALL
Select 4,10,12.00
Union ALL
Select 5,5,10.00
Union ALL
Select 5,10,16.00

-- Create query to dynamically pivot data
Select @sql = 'SELECT p.ProductID, p.ProductName, c.CategoryID, c.CategoryName, '
Select @sql = @sql + STUFF((Select DISTINCT ',MAX(CASE WHEN pp.Seq = ' + Cast(pp.Seq As Varchar) + ' THEN pp.ProductQuantity ELSE null END) As ProductQuantity' + Cast(pp.Seq As Varchar)
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY ProductQuantity) Seq, ProductID, ProductQuantity, ProductCost
FROM productprices
) pp FOR XML PATH('')),1,1,'') + ', '
Select @sql = @sql + STUFF((Select DISTINCT ',MAX(CASE WHEN pp.Seq = ' + Cast(pp.Seq As Varchar) + ' THEN pp.ProductCost ELSE null END) As ProductCost' + Cast(pp.Seq As Varchar)
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY ProductQuantity) Seq, ProductID, ProductQuantity, ProductCost
FROM productprices
) pp FOR XML PATH('')),1,1,'')
Select @sql = @sql + ' FROM product p
INNER JOIN category c ON p.CategoryID = c.CategoryID
INNER JOIN (
SELECT ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY ProductQuantity) Seq, ProductID, ProductQuantity, ProductCost
FROM productprices
) pp ON p.ProductId = pp.ProductID
GROUP BY p.ProductID, p.ProductName, c.CategoryID, c.CategoryName '
Execute(@sql)



Hope this helps.


Good example of a dynamic cross tab, Vinu. Can you change it to put output columns in the same order as requested?


Yes Jeff,

I did manage to get the columns in the order requested by tweaking the code i posted earlier.
Here is the new code with the desired order of columns:

Declare @sql Varchar(MAX) 
-- Set up some test data
Create table product(ProductId Int, ProductName Varchar(30),CategoryID Int)
Create table category(CategoryID Int, CategoryName Varchar(30))
Create table productprices(ProductID Int, ProductQuantity Int, ProductCost Float)
Insert Into product
Select 1, 'Beer', 1
Union ALL
Select 2, 'Wine', 1
Union ALL
Select 3, 'Bourbon', 1
Union ALL
Select 4, 'Crisps', 2
Union ALL
Select 5, 'Nuts', 2
Insert Into category
Select 1,'Beverages'
Union ALL
Select 2,'Snacks'
Insert Into productprices
Select 1,1,2.00
Union ALL
Select 1,12,20.00
Union ALL
Select 1,24,36.00
Union ALL
Select 2,1,12.00
Union ALL
Select 2,6,60.00
Union ALL
Select 3,1,45.00
Union ALL
Select 4,10,12.00
Union ALL
Select 5,5,10.00
Union ALL
Select 5,10,16.00

-- Create query to dynamically pivot data
Select @sql = 'SELECT p.ProductID, p.ProductName, c.CategoryID, c.CategoryName, '
Select @sql = @sql + STUFF((Select DISTINCT ',MAX(CASE WHEN pp.Seq = ' + Cast(pp.Seq As Varchar) + ' THEN pp.ProductQuantity ELSE null END) As ProductQuantity' + Cast(pp.Seq As Varchar) + ',MAX(CASE WHEN pp.Seq = ' + Cast(pp.Seq As Varchar) + ' THEN pp.ProductCost ELSE null END) As ProductCost' + Cast(pp.Seq As Varchar)
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY ProductQuantity) Seq, ProductID, ProductQuantity, ProductCost
FROM productprices
) pp FOR XML PATH('')),1,1,'')
Select @sql = @sql + ' FROM product p
INNER JOIN category c ON p.CategoryID = c.CategoryID
INNER JOIN (
SELECT ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY ProductQuantity) Seq, ProductID, ProductQuantity, ProductCost
FROM productprices
) pp ON p.ProductId = pp.ProductID
GROUP BY p.ProductID, p.ProductName, c.CategoryID, c.CategoryName '
Execute(@sql)

P.S.: Jeff, I'm gonna tell my dba friend's that Jeff Moden liked my solution.......ROFL!!!!!!


Vinu Vijayan

For better and faster solutions please check..."How to post data/code on a forum to get the best help" - Jeff Moden
Post #1437366
« Prev Topic | Next Topic »

Add to briefcase ««12

Permissions Expand / Collapse