【问题标题】:SQL Query for "criss cross" lookup to get a "completed" table用于“交叉”查找的 SQL 查询以获取“已完成”表
【发布时间】:2023-03-11 13:43:01
【问题描述】:

这里的 SQL 新手正在研究如何在 Access 2007 中优化 SQL 查询。我找到的解决方案确实有效,但我一点也不喜欢它,因为我认为这不是一种非常优雅的方法。这是我要的 RESULT 表:

Product  | Manufacturer        | Price
---------|---------------------|-----------------
Apples   | FreshFoods inc.     | n.a.
Oranges  | FreshFoods inc.     | $2.99
Lemons   | FreshFoods inc.     | $1.55
Lemonade | FreshFoods inc.     | n.a.
Apples   | NatureOnlineShop    | $5.00
Oranges  | NatureOnlineShop    | n.a.
Lemons   | NatureOnlineShop    | $4.50
Lemonade | NatureOnlineShop    | n.a.
Apples   | ExpensiveFoods inc. | $16.00
Oranges  | ExpensiveFoods inc. | $49.00
Lemons   | ExpensiveFoods inc. | n.a.
Lemonade | ExpensiveFoods inc. | n.a.

生成自: 1. 表产品

ID | Name    
---|-------- 
1  | Apples  
2  | Oranges
3  | Lemons
4  | Lemonade

2。表制造商

ID | Name
---|--------------------
1  | FreshFoods inc.
2  | NatureOnlineShop
3  | ExpensiveFoods inc.

和 3. 表价格

ID | ID_Product | ID_Manufacturer | Price
---|------------|-----------------|----------
1  | 2          | 1               | $2.99
2  | 3          | 1               | $1.55
3  | 3          | 2               | $4.50
4  | 1          | 2               | $5.00
5  | 1          | 3               | $16.00
6  | 2          | 3               | $49.00

我所拥有的(一起破解)并且有效的是:

SELECT      
          PRODUCTS.Name as Product, MANUFACTURER.Name as Manufacturer, PRICES.Price as Price
FROM    
          PRODUCTS, MANUFACTURER, PRICES
WHERE 
          PRICES.ID_Product = PRODUCTS.ID AND
          PRICES.ID_Manufacturer = MANUFACTURER.ID 

UNION SELECT    

          PRODUCTS.Name as Product, MANUFACTURER.Name as Manufacturer, "n.a." as Price
FROM      
          PRODUCTS, MANUFACTURER
WHERE   
          (10000*PRODUCTS.ID + MANUFACTURER.ID) 
          NOT IN 
          (SELECT 10000*PRICES.ID_Product + PRICES.ID_Manufacturer FROM PRICES)

我特别不喜欢 10000*.. 部分,并且会感谢如何进行这些“完成的十字交叉”查找的替代解决方案。不知道这些是如何被调用的。

【问题讨论】:

    标签: sql ms-access ms-access-2007


    【解决方案1】:

    PRODUCTSMANUFACTURER 之间以 implicit CROSS JOIN 开头:

    SELECT
        PRODUCTS.ID AS ID_Product,
        PRODUCTS.Name AS Name_Product,
        MANUFACTURER.ID AS ID_Manufacturer,
        MANUFACTURER.Name AS Name_Manufacturer
    FROM PRODUCTS, MANUFACTURER;
    

    然后您可以将其用作您LEFT JOINPRICES 的子查询。我在 Access 2010 中测试了这个查询,它返回了我认为你想要的行,但你可能需要调整它们的顺序:

    SELECT
        sub.Name_Product AS [Product],
        sub.Name_Manufacturer AS [Manufacturer],
        IIf(
                PRICES.Price Is Null,
                'n.a.',
                Format(PRICES.Price,'$0.00')
            ) AS [Price]
    FROM
        (
            SELECT
                PRODUCTS.ID AS ID_Product,
                PRODUCTS.Name AS Name_Product,
                MANUFACTURER.ID AS ID_Manufacturer,
                MANUFACTURER.Name AS Name_Manufacturer
            FROM PRODUCTS, MANUFACTURER
        ) AS sub
        LEFT JOIN PRICES
        ON
                (sub.ID_Manufacturer = PRICES.ID_Manufacturer)
            AND (sub.ID_Product = PRICES.ID_Product);
    

    【讨论】:

      【解决方案2】:

      您似乎希望产品和制造商的每个组合都有一行,无论该组合是否有价目表。如果有价格列表,您希望将其包含在结果中。

      有趣的是,您将其称为“交叉”查找,因为“CROSS JOIN”是 SQL 术语,用于获取行的所有组合,一个来自一个表,一个来自另一个,这正是您想要的第一部分.您实际上不必说“CROSS”部分。

      对于给定(产品、制造商)没有价格的情况,这就是外连接的用途。

      此作业的更常规 SQL 可能如下所示:

      SELECT
        PRODUCTS.Name AS Product,
        MANUFACTURER.Name AS Manufacturer,
        COALESCE(PRICES.Price, 'n.a.') AS Price
      FROM
        PRODUCTS
        JOIN MANUFACTURER
        LEFT OUTER JOIN PRICES
          ON PRICES.ID_Product = PRODUCTS.ID
            AND PRICES.ID_Manufacturer = MANUFACTURER.ID
      

      假设您的价格实际上是字符串,因此将它们存储在与字符串“n.a.”相同的结果列中是有意义的。如果它们是数字数据类型,那么您最好只在结果中接受 NULL 而不是字符串 'n.a.'。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-23
        • 1970-01-01
        • 1970-01-01
        • 2015-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-18
        相关资源
        最近更新 更多