【问题标题】:SQL Select Query - problem pivoting rows into columnsSQL Select Query - 将行转换为列的问题
【发布时间】:2011-06-08 15:06:49
【问题描述】:

我在 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 和 sales 上删除 shopID 联接,它会显示库存水平,但会报告不准确的销售额 - 乘以四(每个 shopstock 记录一个?)。

我知道我在这里遗漏了一些东西,但我没有得到任何地方!任何帮助都将受到极大的欢迎。

【问题讨论】:

    标签: sql sql-server-2005 pivot


    【解决方案1】:

    两个问题:

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

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

    类似这样的:

    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 过滤器上设置 >=,但这只是一种预感。

    祝你好运!

    【讨论】:

    • 没有汗水。这些枢轴查询对我来说很重要。在招聘新开发人员时,我将它们用作面试问题。他们几乎从来没有把它们做对,但看着它们蠕动很有趣。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-17
    • 2017-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多