选择未订购或没有订购且具有成功状态的产品

时间:2019-05-06 14:21:21

标签: mysql

给出产品和订单表。 我想获得从未订购或未订购但订购状态从未成功的产品。

要获取从未订购的产品,请使用以下查询:

SELECT *
FROM products p
LEFT JOIN orders o ON p.product_id=o.product_id
WHERE order_id IS NULL
GROUP BY p.product_id;

我认为这个查询还可以。

要获取从未订购或未订购但order_status失败或中断的产品,我使用以下查询:

SELECT *
FROM products p
LEFT JOIN orders o ON p.product_id=o.product_id
WHERE (order_id IS NULL OR (order_id>0 AND (order_status=5 OR order_status=9))
GROUP BY p.product_id;

它没有给出我想要的东西,因为如果某产品被订购两次且一次订购成功(order_status为4)而一次订购失败(order_status为5),则给定产品将处于结果中。但是我需要永远不会成功的产品。

3 个答案:

答案 0 :(得分:0)

您应该在ON子句中移动与eft联接表相关的列的条件

SELECT *
FROM products p
LEFT JOIN orders o ON p.product_id=o.product_id 
      AND (order_id IS NULL OR (order_id>0 AND (order_status=5 OR order_status=9))

将与左联接表相关的where列用作内部联接(不会为这些行产生结果)

并且您不应该使用没有聚合功能的分组方式,这对于mysql版本<5.7产生不可预测的结果,并且默认情况下对于mysql版本> = 5.7不允许使用

对group by子句中未调用的列使用distinct或添加适当的聚合函数

SELECT p.product_id, max(col1), max(col2) ..... 
FROM products p
LEFT JOIN orders o ON p.product_id=o.product_id 
      AND (order_id IS NULL OR (order_id>0 AND (order_status=5 OR order_status=9))
GROUP BY p.product_id;

答案 1 :(得分:0)

如何使用子查询。

SELECT *
FROM products p
WHERE p.product_id NOT IN (
     --This query returns all successfull orders
     select product_id from orders where order_id > 0 and order_status = 4
    )

答案 2 :(得分:0)

使用第一个查询的逻辑,并在ON子句中添加其他条件:

SELECT p.*
FROM products p
LEFT JOIN orders o
  ON  o.product_id   = p.product_id
  AND o.order_status = 4
WHERE order_id IS NULL

请注意,您在这里不需要GROUP BY,因为每种产品每种方式都只会获得一行(假设orders.order_id是主键)。

该查询等同于

SELECT p.*
FROM products p
WHERE NOT EXISTS (
    SELECT *
    FROM orders o
    WHERE o.product_id   = p.product_id
      AND o.order_status = 4
)

这可以理解为“选择状态为4(成功)的所有没有订单的产品”。

如果您的逻辑是“选择没有订单或状态为5或9的所有产品”-那么您可以使用

SELECT p.*
FROM products p
LEFT JOIN orders o
  ON  o.product_id   = p.product_id
  AND o.order_status NOT IN (5, 9)
WHERE order_id IS NULL