I have three tables in an SQL 2005 database, that I need to query and display on one row. The tables are:
MasterStock
StockID, Description
1, Plate
2, Bowl
ShopStock
ShopID, StockID, StockLevel
1,1,6
2,1,0
3,1,0
4,1,10
Sales
StockId, ShopId, SoldQuantity, transDate
1, 1, 1, 5/1/2011
1,2,1, 5/1/2011
I need to get them to show one row:
StockID, Description, 1 Sales, 1 Stock, 2 Sales, 2 Stock, 3 Sales,…
I have managed to get what somewhere with the query below:
SELECT MasterStock.StockID, MasterStock.Description,
SUM(CASE WHEN sales.shopid = 1 THEN sales.Soldquantity ELSE 0 END) AS [1 Sold],
MAX(CASE WHEN shopstock.shopid = 1 THEN shopstock.stockLevel ELSE 0 END) AS [1 Stock],
SUM(CASE WHEN sales.shopid = 2 THEN sales.Soldquantity ELSE 0 END) AS [2 Sold],
MAX(CASE WHEN shopstock.shopid = 2 THEN shopstock.stockLevel ELSE 0 END) AS [2 Stock],
SUM(CASE WHEN sales.shopid = 3 THEN sales.Soldquantity ELSE 0 END) AS [3 Sold],
MAX(CASE W开发者_开发百科HEN shopstock.shopid = 3 THEN shopstock.stockLevel ELSE 0 END) AS [3 Stock],
SUM(CASE WHEN sales.shopid = 4 THEN sales.Soldquantity ELSE 0 END) AS [4 Sold],
MAX(CASE WHEN shopstock.shopid = 4 THEN shopstock.stockLevel ELSE 0 END) AS [4 Stock]
FROM ShopStock INNER JOIN
Sales ON ShopStock.StockID = Sales.StockID AND ShopStock.shopID = Sales.ShopID
INNER JOIN MasterStock ON ShopStock.StockID = MasterStock.StockID
WHERE (sales.transdate > 1/1/2010)
GROUP BY MasterStock.StockID, MasterStock.Description
However, if there are no sales for the product it doesn’t show any stock levels. If I remove the shopID join on shopstock and sales it shows the stock levels, but reports inaccurate sales - multiplies by four (one for each shopstock record?).
I know I’m missing something here, but I’m not getting anywhere! Any help would be greatly received.
Two problems:
1) You need a LEFT OUTER JOIN between ShopStock and Sales, which will ensure that the query returns records from ShopStock even if there are no related entries in Sales. By definition, an INNER JOIN will not return records from either side of the join, if one of the sides is missing records.
2) You need to move your sales.transdate > 1/1/2010 condition to the inner join, rather than the WHERE clause. Conditions in the WHERE clause will be logically applied after any logic in the table joins. So even if you get your joins right, the where clause will filter out stock without sales because sales.transdate will appear null.
Something like this:
FROM ShopStock LEFT OUTER JOIN Sales
ON ShopStock.StockID = Sales.StockID
AND Sales.transdate > 1/1/2010
INNER JOIN // the rest of your joins here
I'm guessing you also want >= on your transdate filter as well, but that's just a hunch.
Good luck!
精彩评论