在 WHERE 子句中使用子查询,但每个子查询结果限制为一个匹配项
Using a subquery to in WHERE clause but limiting to one match per sub query result
我正在使用 MariaDB。
我有两个 table,REPLEN 存储销售的产品、数量和销售日期等,另一个是主要的产品 table,包含描述、库存代码、库存数量、最后日期交付等。STOCK_CODE 很重要,因为相同的匹配项由该产品的替代品共享。
我想使用此库存代码查找 REPLEN 中现在缺货但有库存的任何条目的替代品。我想将此限制为每场比赛一个替代方案,并且该替代方案是为库存轮换目的交付的最旧的替代方案。
table 看起来像这样:
补充:
PROD_ID QTY_SOLD DATE_LAST_SOLD
4552 6 2020-10-28
8612 2 2020-11-14
7661 1 2020-11-15
9891 5 2020-11-17
这是通过 PROD_ID KEY 与产品 table 相关联的
PRODUCT_ID DESCRIPTION STOCK_CODE STOCK_QTY DATE_LDELIV
4552 Cashew Nuts Best Buy NUTS CASHEW 0 2020-11-01
8612 Baked Beans SaveMore BEANS BUDGET 0 2020-08-12
7661 Nestle Instant Coffee COFFEE INSTANT 40 2020-10-20
9891 Heinz Baked Beans BEANS HEINZ 12 2020-10-09
10988 Baked Beans Supersaver BEANS BUDGET 10 2020-11-04
11092 Baked Beans BestBuy BEANS BUDGET 14 2020-10-27
12093 Cashew Nuts Supersaver NUTS CASHEW 24 2020-11-18
现在产品 4552 和 8612 缺货,所以告诉别人补货没有任何意义。但是,我真的不在乎货架上有什么品牌的预算豆或腰果,所以其他两种产品也共享 BEANS BUDGET stock_code 和 1 个其他产品共享 NUTS CASHEW 所有这些都有库存。
我想要一个 SELECT QUERY 来找到它们!
所以首先我有一个查询,查找 REPLEN 中没有库存的任何产品的所有 STOCK_CODE
SELECT p.STOCK_CODE FROM product p JOIN replen r ON p.PRODUCT_ID=r.PROD_ID WHERE p.STOCK_QTY <=0
这个returns“BEANS_BUDGET”和“NUTS CASHEW”
然后我可以将其用作子查询来查找有货的产品并共享 Stock_code
SELECT p.PRODUCT_ID, p.STOCK_CODE, p.DATE_LDELIV FROM product p
WHERE p.STOCK_CODE IN
(SELECT p.STOCK_CODE FROM product p
JOIN replen r ON p.PRODUCT_ID=r.PROD_ID
WHERE p.STOCK_QTY <=0)
AND p.STOCK_QTY > 0
但是这 return 所有替代产品:
PRODUCT_ID STOCK_CODE DATE_LDELIV
10988 BEANS BUDGET 2020-11-04
11092 BEANS BUDGET 2020-10-27
12093 NUTS CASHEW 2020-11-18
我的架子上只有 space 一排 Budget Bean!
这就是我卡住的地方。我可以添加 GROUP BY:
SELECT p.PRODUCT_ID, p.STOCK_CODE, p.DATE_LDELIV FROM product p
WHERE p.STOCK_CODE IN
(SELECT p.STOCK_CODE FROM product p
JOIN replen r ON p.PRODUCT_ID=r.PROD_ID
WHERE p.STOCK_QTY <=0)
AND p.STOCK_QTY > 0 GROUP BY STOCK_CODE
但是这个 returns:
PRODUCT_ID STOCK_CODE DATE_LDELIV
10988 BEANS BUDGET 2020-11-04
12093 NUTS CASHEW 2020-11-18
问题是产品 11092 是旧库存,所以我希望 returned 而不是 10988。
我不能在 GROUP BY 之前使用 ORDER BY。即使我可以(通过使用别名将查询包装在另一个查询中)它总是 returns 10988 因为 MariaDB 在设计上忽略了子查询结果中的任何顺序。
需要的是一个查询,该查询将 return 只有一种选择,即 OLDEST Delivered 产品。本质上,我希望它 return:
PRODUCT_ID STOCK_CODE DATE_LDELIV
11092 BEANS BUDGET 2020-10-27
12093 NUTS CASHEW 2020-11-18
求助!
您可以应用 ROW_NUMBER 来获取最早日期的行:
SELECT *
FROM
(
SELECT p.PRODUCT_ID, p.STOCK_CODE, p.DATE_LDELIV,
ROW_NUMBER() OVER (PARTITION BY STOCK_CODE ORDER BY DATE_LDELIV) as rn
FROM product p
WHERE p.STOCK_CODE IN
(SELECT p.STOCK_CODE FROM product p
JOIN replen r ON p.PRODUCT_ID=r.PROD_ID
WHERE p.STOCK_QTY <=0)
AND p.STOCK_QTY > 0
) as dt
WHERE rn = 1
让我们从这个几乎有效的查询开始:
SELECT p.PRODUCT_ID, p.STOCK_CODE, p.DATE_LDELIV
FROM product p JOIN
WHERE p.STOCK_CODE IN (SELECT p.STOCK_CODE
FROM product p JOIN
replen r
ON p.PRODUCT_ID = r.PROD_ID
WHERE p.STOCK_QTY <= 0
) AND
p.STOCK_QTY > 0
接下来,我将加入 replen
table 以获取最早的日期:
SELECT p.PRODUCT_ID, p.STOCK_CODE, p.DATE_LDELIV, r.date_last_sold,
ROW_NUMBER() OVER (PARTITION BY p.PRODUCT_ID ORDER BY r.date_last_sold) as seqnum
FROM product p JOIN
replen r
ON p.PRODUCT_ID = r.PROD_ID
WHERE p.STOCK_CODE IN (SELECT p.STOCK_CODE
FROM product p JOIN
replen r
ON p.PRODUCT_ID = r.PROD_ID
WHERE p.STOCK_QTY <= 0
) AND
p.STOCK_QTY > 0;
然后将其用作子查询以获取所需的每个产品一行:
SELECT p.*
FROM (SELECT p.PRODUCT_ID, p.STOCK_CODE, p.DATE_LDELIV, r.date_last_sold,
ROW_NUMBER() OVER (PARTITION BY p.PRODUCT_ID ORDER BY r.date_last_sold) as seqnum
FROM product p JOIN
replen r
ON p.PRODUCT_ID = r.PROD_ID
WHERE p.STOCK_CODE IN (SELECT p.STOCK_CODE
FROM product p JOIN
replen r
ON p.PRODUCT_ID = r.PROD_ID
WHERE p.STOCK_QTY <= 0
) AND
p.STOCK_QTY > 0
) p
WHERE seqnum = 1;
我正在使用 MariaDB。
我有两个 table,REPLEN 存储销售的产品、数量和销售日期等,另一个是主要的产品 table,包含描述、库存代码、库存数量、最后日期交付等。STOCK_CODE 很重要,因为相同的匹配项由该产品的替代品共享。
我想使用此库存代码查找 REPLEN 中现在缺货但有库存的任何条目的替代品。我想将此限制为每场比赛一个替代方案,并且该替代方案是为库存轮换目的交付的最旧的替代方案。
table 看起来像这样:
补充:
PROD_ID QTY_SOLD DATE_LAST_SOLD
4552 6 2020-10-28
8612 2 2020-11-14
7661 1 2020-11-15
9891 5 2020-11-17
这是通过 PROD_ID KEY 与产品 table 相关联的
PRODUCT_ID DESCRIPTION STOCK_CODE STOCK_QTY DATE_LDELIV
4552 Cashew Nuts Best Buy NUTS CASHEW 0 2020-11-01
8612 Baked Beans SaveMore BEANS BUDGET 0 2020-08-12
7661 Nestle Instant Coffee COFFEE INSTANT 40 2020-10-20
9891 Heinz Baked Beans BEANS HEINZ 12 2020-10-09
10988 Baked Beans Supersaver BEANS BUDGET 10 2020-11-04
11092 Baked Beans BestBuy BEANS BUDGET 14 2020-10-27
12093 Cashew Nuts Supersaver NUTS CASHEW 24 2020-11-18
现在产品 4552 和 8612 缺货,所以告诉别人补货没有任何意义。但是,我真的不在乎货架上有什么品牌的预算豆或腰果,所以其他两种产品也共享 BEANS BUDGET stock_code 和 1 个其他产品共享 NUTS CASHEW 所有这些都有库存。
我想要一个 SELECT QUERY 来找到它们!
所以首先我有一个查询,查找 REPLEN 中没有库存的任何产品的所有 STOCK_CODE
SELECT p.STOCK_CODE FROM product p JOIN replen r ON p.PRODUCT_ID=r.PROD_ID WHERE p.STOCK_QTY <=0
这个returns“BEANS_BUDGET”和“NUTS CASHEW”
然后我可以将其用作子查询来查找有货的产品并共享 Stock_code
SELECT p.PRODUCT_ID, p.STOCK_CODE, p.DATE_LDELIV FROM product p
WHERE p.STOCK_CODE IN
(SELECT p.STOCK_CODE FROM product p
JOIN replen r ON p.PRODUCT_ID=r.PROD_ID
WHERE p.STOCK_QTY <=0)
AND p.STOCK_QTY > 0
但是这 return 所有替代产品:
PRODUCT_ID STOCK_CODE DATE_LDELIV
10988 BEANS BUDGET 2020-11-04
11092 BEANS BUDGET 2020-10-27
12093 NUTS CASHEW 2020-11-18
我的架子上只有 space 一排 Budget Bean!
这就是我卡住的地方。我可以添加 GROUP BY:
SELECT p.PRODUCT_ID, p.STOCK_CODE, p.DATE_LDELIV FROM product p
WHERE p.STOCK_CODE IN
(SELECT p.STOCK_CODE FROM product p
JOIN replen r ON p.PRODUCT_ID=r.PROD_ID
WHERE p.STOCK_QTY <=0)
AND p.STOCK_QTY > 0 GROUP BY STOCK_CODE
但是这个 returns:
PRODUCT_ID STOCK_CODE DATE_LDELIV
10988 BEANS BUDGET 2020-11-04
12093 NUTS CASHEW 2020-11-18
问题是产品 11092 是旧库存,所以我希望 returned 而不是 10988。
我不能在 GROUP BY 之前使用 ORDER BY。即使我可以(通过使用别名将查询包装在另一个查询中)它总是 returns 10988 因为 MariaDB 在设计上忽略了子查询结果中的任何顺序。
需要的是一个查询,该查询将 return 只有一种选择,即 OLDEST Delivered 产品。本质上,我希望它 return:
PRODUCT_ID STOCK_CODE DATE_LDELIV
11092 BEANS BUDGET 2020-10-27
12093 NUTS CASHEW 2020-11-18
求助!
您可以应用 ROW_NUMBER 来获取最早日期的行:
SELECT *
FROM
(
SELECT p.PRODUCT_ID, p.STOCK_CODE, p.DATE_LDELIV,
ROW_NUMBER() OVER (PARTITION BY STOCK_CODE ORDER BY DATE_LDELIV) as rn
FROM product p
WHERE p.STOCK_CODE IN
(SELECT p.STOCK_CODE FROM product p
JOIN replen r ON p.PRODUCT_ID=r.PROD_ID
WHERE p.STOCK_QTY <=0)
AND p.STOCK_QTY > 0
) as dt
WHERE rn = 1
让我们从这个几乎有效的查询开始:
SELECT p.PRODUCT_ID, p.STOCK_CODE, p.DATE_LDELIV
FROM product p JOIN
WHERE p.STOCK_CODE IN (SELECT p.STOCK_CODE
FROM product p JOIN
replen r
ON p.PRODUCT_ID = r.PROD_ID
WHERE p.STOCK_QTY <= 0
) AND
p.STOCK_QTY > 0
接下来,我将加入 replen
table 以获取最早的日期:
SELECT p.PRODUCT_ID, p.STOCK_CODE, p.DATE_LDELIV, r.date_last_sold,
ROW_NUMBER() OVER (PARTITION BY p.PRODUCT_ID ORDER BY r.date_last_sold) as seqnum
FROM product p JOIN
replen r
ON p.PRODUCT_ID = r.PROD_ID
WHERE p.STOCK_CODE IN (SELECT p.STOCK_CODE
FROM product p JOIN
replen r
ON p.PRODUCT_ID = r.PROD_ID
WHERE p.STOCK_QTY <= 0
) AND
p.STOCK_QTY > 0;
然后将其用作子查询以获取所需的每个产品一行:
SELECT p.*
FROM (SELECT p.PRODUCT_ID, p.STOCK_CODE, p.DATE_LDELIV, r.date_last_sold,
ROW_NUMBER() OVER (PARTITION BY p.PRODUCT_ID ORDER BY r.date_last_sold) as seqnum
FROM product p JOIN
replen r
ON p.PRODUCT_ID = r.PROD_ID
WHERE p.STOCK_CODE IN (SELECT p.STOCK_CODE
FROM product p JOIN
replen r
ON p.PRODUCT_ID = r.PROD_ID
WHERE p.STOCK_QTY <= 0
) AND
p.STOCK_QTY > 0
) p
WHERE seqnum = 1;