SQL选择查询 - 将行转换为列的问题

时间:2011-06-08 15:06:49

标签: sql sql-server-2005 pivot

我在SQL 2005数据库中有三个表,我需要查询并显示在一行上。表格是:

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

我需要让它们显示一行:

StockID,描述,1个销售,1个股票,2个销售,2个股票,3个销售,......

我已经设法通过以下查询得到了什么:

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

但是,如果产品没有销售,则不会显示任何库存水平。如果我删除shopstock加入shopstock和销售它显示库存水平,但报告不准确的销售 - 乘以四(每个shopstock记录一个?)。

我知道我在这里遗漏了一些东西,但我没有到达任何地方!任何帮助都会得到很大的帮助。

1 个答案:

答案 0 :(得分:1)

两个问题:

1)您需要在ShopStock和Sales之间进行LEFT OUTER JOIN,这将确保查询从ShopStock返回记录,即使Sales中没有相关条目。根据定义,如果其中一方缺少记录,INNER JOIN将不会从联接的 侧返回记录。

2)您需要移动sales.transdate> 2010年1月1日条件到内部联接,而不是WHERE子句。在表连接中的任何逻辑之后,WHERE子句中的条件将在逻辑上应用。因此,即使您的联接正确,where子句也会在没有销售的情况下过滤掉库存,因为sales.transdate将显示为null。

这样的事情:

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

我猜你也想在你的transdate过滤器上使用> =但这只是一种预感。

祝你好运!