多个子查询中的复杂连接

use*_*168 2 join sql-server subquery count where

很抱歉一直打扰你们,但 SQL 对我来说仍然是新的。我有这些表:Store_location、Product、Sizes、Sells、Available_in、Offers 和 Currency。目标是能够运行一个包含多个子查询的查询(需要WHERE子句),该查询将仅返回在所有商店位置销售的产品,而不返回其他任何内容。它还必须是可扩展的,这样如果任何商店打开或关闭,代码就不需要更改。我有这些杂谈让我开始,但我不知道从哪里开始:下面的第一个 select 语句是查询成功时需要显示的内容。SELECT Store_location.store_name,Product.product_name,Sizes.size_option, COUNT(store_location.store_id) AS store_count

JOIN Sells ON Sells.store_location_id = Store_location.store_location_id
JOIN Product ON Product.product_id = Sells.product_id


JOIN ON Available_in.product_id = Product.product_id
JOIN ON Available_in.sizes_id = Sizes.sizes_id
Run Code Online (Sandbox Code Playgroud)

我试图完成连接以显示我需要使用的表在哪里有外键约束。如果您需要任何其他信息,我可以提供。我添加了一个链接,显示所有相关表格的内容。我知道我需要在 WHERE 语句中嵌入至少一个子查询,但不确定在那里放什么。我知道有很多信息需要回顾,我理解如果没有人有时间提供帮助,但任何指导都将不胜感激。

我意识到这是一个迟到的请求,但如果有人能帮助我在这方面也使用EXISTS,我将不胜感激。

RDF*_*ozz 5

如果要找出所有商店都出售哪些产品,这似乎是最困难的部分。与大多数事情一样,有不止一种方法可以做到这一点,但以下查询应返回所有商店中销售的所有产品 ID:

SELECT product_id
  FROM Product
EXCEPT -- exclude product IDs that are not sold in all stores
SELECT product_id
  FROM (-- Generate list of product IDs and the stores that do NOT sell them
        -- select all possible products and stores ...
        SELECT product_id, store_id
          FROM Product CROSS JOIN Store_location
        EXCEPT -- ... for the products actually sold by each store
        SELECT product_id, store_id
          FROM Sells
       ) Not_At_All_Stores
Run Code Online (Sandbox Code Playgroud)

子查询获取所有可能的产品和商店的列表,并删除代表在相关商店中实际销售的产品的组合。这只会留下不在指定商店出售的产品。

然后,我们获取产品的完整列表,并删除我们(现在)知道至少在一家商店没有销售的任何产品。只剩下所有商店出售的产品。

从这里开始,这只是将所有东西连接在一起的问题。你会得到这样的 FROM 子句:

SELECT Store_location.store_name
      ,Product.product_name
      ,Sizes.size_option
  FROM (
        SELECT product_id
          FROM Product
        EXCEPT -- exclude product IDs that are not sold in all stores
        SELECT product_id
          FROM (-- Generate list of product IDs and the stores that do NOT sell them
                -- select all possible products and stores ...
                SELECT product_id, store_id
                  FROM Product CROSS JOIN Store_location
                EXCEPT -- ... for the products actually sold by each store
                SELECT product_id, store_id
                  FROM Sells
               ) Not_At_All_Stores
       ) uprod -- for a Universally sold PRODuct
         INNER JOIN Product ON (uprod.product_id = Product.product_id)
         INNER JOIN Available_in ON (uprod.product_id = Available_in.product_id
           INNER JOIN Sizes ON (Available_in.size_id = Sizes.size_id)
         INNER JOIN Sells ON (uprod.product_id = Sells.product_id)
           INNER JOIN Store_location ON (Sells.store_id = Store_location.store_id)
 ORDER BY store_name, product_name, size_option
Run Code Online (Sandbox Code Playgroud)

不需要任何WHERE条款(根据您的要求)。请注意,商店信息是多余的 - 因为这些产品在所有商店都有销售,所以您只会获得相同基础结果的 5 个副本,每个副本都附加了 5 个商店名称之一。对于并非在每家商店出售的产品,商店名称更有趣。

注意:根据Product表的索引方式,您可以将product_name列添加到Not_At_All_Stores子查询中,并从那里执行。但是,这确实意味着我们必须将其包含在所有可能的产品和商店的列表中,这会在执行 EXCEPT 操作时消耗更多内存。

更新:从您的最新评论来看,显然这个赋值要求您使用 WHERE 子句、WHERE 子句中的子查询和 EXISTS。从这里到达那里:

  • uprod从查询中删除;链接到的任何内容都uprod.product_id应该链接到Product.product_id
  • 使用 may answer 中的第一个查询作为您的子查询;
  • 您需要 product_id 存在于子查询中的记录。

既然这家庭作业,我会让你真正组装它,至少。

使用我的答案中的第一个查询作为您的子查询,并查找产品