如何为以下操作创建 SQL 查询?

Posted

技术标签:

【中文标题】如何为以下操作创建 SQL 查询?【英文标题】:How to create a SQL query for the following operation? 【发布时间】:2015-06-23 19:12:04 【问题描述】:

我希望你能帮助我。我刚开始学习 SQL,在工作中应用我的知识时,我被卡住了。我有多个表的 SQL 数据库,其中包含出售物品属性的各种数据。到目前为止,我成功创建了一个查询,它提取了大部分所需的信息。不幸的是,最后一张表对我来说有问题。表的格式如下:
| fkStockItemId  | PropertyName | PropertyValue | PropertyType |
|   ItemSKU-1    |  Item Style  |   SB-01123    |   Attribute  |
|   ItemSKU-1    |  Item Size   |    X-Small    |   Attribute  |
|   ItemSKU-1    |  Item Color  |      Red      |   Attribute  |
|   ItemSKU-2    |  Item Style  |   AA-66002    |   Attribute  |
|   ItemSKU-2    |  Item Size   |    Medium     |   Attribute  |
|   ItemSKU-2    |  Item Color  |     Green     |   Attribute  |                            
|   ItemSKU-3    |  Item Style  |    110445     |   Attribute  |
|   ItemSKU-3    |  Item Size   |     Small     |   Attribute  |

我想得到的输出是这样的:

    |    SKU    |  Item Style  |  Item Size  | Item Color  | 
    | ItemSKU-1 |   SB-01123   |   X-Small   |    Red      |
    | ItemSKU-2 |   AA-66002   |   Medium    |    Green    |
    | ItemSKU-3 |    110445    |    Small    |   *Null*    | 


    Please note that last column "PropertyType" is for technical purposes and 
is not needed to be queried.

这是我目前得到的:

SELECT si.ItemNumber, si.ItemTitle, si.ItemDescription, si.RetailPrice, si.Weight, sl.Quantity, c.CategoryName, siep.ProperyValue, siep.ProperyName
FROM StockItem si
LEFT OUTER JOIN StockLevel sl ON si.pkStockItemID = sl.fkStockItemId
LEFT OUTER JOIN ProductCategories c ON si.CategoryId = c.CategoryId
LEFT OUTER JOIN StockItem_ExtendedProperties siep ON si.pkStockItemID = siep.fkStockItemId
WHERE siep.ProperyName = 'Item Style'

表“StockLevel”和“ProductCategories”显示结果很好。如果您注意到,最后“StockItem_ExtendedProperties”JOIN 和“siep.ProperyValue”、“siep.ProperyName”加上“WHERE siep.ProperyName = 'Item Style'”只允许我查询 1 个属性。感谢您的帮助和时间!

【问题讨论】:

【参考方案1】:

将属性名过滤器从 WHERE 子句移至 ON 子句。然后为每个属性再次加入:

SELECT si.ItemNumber, si.ItemTitle, si.ItemDescription, si.RetailPrice, si.Weight, sl.Quantity, c.CategoryName, style.ProperyValue as style, size.ProperyValue as size
FROM StockItem si
LEFT OUTER JOIN StockLevel sl ON si.pkStockItemID = sl.fkStockItemId
LEFT OUTER JOIN ProductCategories c ON si.CategoryId = c.CategoryId
LEFT OUTER JOIN StockItem_ExtendedProperties style ON si.pkStockItemID = style.fkStockItemId
AND style.ProperyName = 'Item Style'
LEFT OUTER JOIN StockItem_ExtendedProperties size ON si.pkStockItemID = size.fkStockItemId
AND size.ProperyName = 'Item Size'

【讨论】:

嗯,查询给我以下错误:在 FROM 子句中多次指定相关名称“样式”。 抱歉,我在加入该表时都将其命名为相同的名称。立即试用编辑后的版本。 好的 nvm 我知道问题出在哪里 哇,这太美了。好的 1 件小事。 “样式”列按预期显示项目的多种样式。但是最后一列“大小”实际上显示了每个项目都重复的“项目大小”?非常感谢您的帮助! 我太草率了,但我希望你能大致了解。您以不同的别名多次加入同一个属性表,以获得所需的属性。我又编辑了。【参考方案2】:

要像这样获取列中的每个值,您可以先为每个属性编写一个子查询,然后将它们一起JOIN它们,如下所示:

SELECT m1.fkStockItemId, m1.propertyValue AS 'Item Style', m2.propertyValue AS 'Item Size', m3.propertyValue AS 'Item Color'
FROM(
  SELECT fkStockItemId, propertyValue
  FROM myTable
  WHERE propertyName = 'Item Style') m1
LEFT JOIN(
  SELECT fkStockItemId, propertyValue
  FROM myTable
  WHERE propertyName = 'Item Size') m2 ON m2.fkStockItemId = m1.fkStockItemId
LEFT JOIN(
  SELECT fkStockItemId, propertyValue
  FROM myTable
  WHERE propertyName = 'Item Color') m3 ON m3.fkStockItemId = m2.fkStockItemId;

这是一个SQL Fiddle 示例。

【讨论】:

您好!感谢您的贡献。你的答案基本上是一种不同的方式吗?老实说,我从没想过 SQL 可以如此灵活。不是在我开始学习它的 w3schools 网站上! 可能有更好的方法,因为这个方法看起来有点笨重,但这是我首先想到的。有用吗? 我现在正在尝试。即使第一个答案完全符合我的要求,我也很想尝试其他方式。【参考方案3】:

我认为最好的方法是创建一个函数,该函数将返回您需要的属性值以及您在查询中包含的内容。

CREATE FUNCTION dbo.GetItemProperty
(
    @ItemName AS VARCHAR(50)
    , @Property AS VARCHAR(8)
)
RETURNS VARCHAR(50)
AS
BEGIN

    DECLARE @Ans AS VARCHAR(50) = ''

    SELECT  @Ans = PropertyValue 
    FROM    StockItem AS si
    JOIN    StockItem_ExtendedProperties AS siep 
            ON si.pkStockItemID = siep.fkStockItemId
    WHERE   si.pkStockItemID = @ItemName
            AND siep.ProperyName = @Property

    RETURN @Ans;

END
GO

SELECT  si.ItemNumber, 
        si.ItemTitle, 
        si.ItemDescription, 
        si.RetailPrice, 
        si.Weight, 
        sl.Quantity, 
        c.CategoryName, 
        dbo.GetItemProperty(si.pkStockItemID, 'Item Style') AS 'Item Style', 
        dbo.GetItemProperty(si.pkStockItemID, 'Item Size') AS 'Item Size', 
        dbo.GetItemProperty(si.pkStockItemID, 'Item Color') AS 'Item Color'
FROM StockItem si
LEFT OUTER JOIN StockLevel sl 
    ON si.pkStockItemID = sl.fkStockItemId
LEFT OUTER JOIN ProductCategories c 
    ON si.CategoryId = c.CategoryId
LEFT OUTER JOIN StockItem_ExtendedProperties siep 
    ON si.pkStockItemID = siep.fkStockItemId;

祝你好运!

【讨论】:

这适用于 SQL 吗?我可以直接输入这个函数作为查询吗? 上述查询为 SQL Server 创建了一个函数。首先运行创建函数的函数,然后运行 ​​select。明白我的意思吗?

以上是关于如何为以下操作创建 SQL 查询?的主要内容,如果未能解决你的问题,请参考以下文章

如何为ZF2中使用Sql对象创建的Sql语句的结果集设置数组对象原型

如何为 PL SQL 中的现有表创建唯一 ID?

如何为以下 Scenerio 编写 linq 查询 [关闭]

如何为每一行编写加入日期时间的 SQL 查询

如何为客户特定数据使用通用变量

如何为SQL Server数据库中的所有表创建触发器