1

我有一张包含商店订单产品的表格

+----------------------------+
| orders_id | products_model |
+----------------------------+
|   1000    | aa0000001      |
|   1000    | bb0000002      |
|   1000    | cc0000001      |
|   1001    | aa0000001      |
|   1002    | bb0000001      |
|   1003    | cc0000001      |
|   1004    | bb0000001      |
|   1004    | aa0000001      |
+----------------------------+

当然,每个订单可以有一个或多个项目

我需要一个仅包含代码以 aa 或 bb(或两者)开头的项目的订单列表 我不想列出包含代码以其他代码类型开头的项目的订单。

例子:

+-----------+
| orders_id |
+-----------+
|   1001    |         
|   1002    | 
|   1004    |
+-----------+

订单 1000 必须被排除,因为它在 'aa' 和 'bb' 旁边有一个 'cc' 项目 订单 1003 必须被排除,因为它有一个 'cc' 项目

我开始尝试比较每个订单的匹配记录数和所有记录数......但我很快就不得不停下来......我是一个 sql 新手,所以我迷失在嵌套查询的丛林中:)

请你帮助我好吗?

4

3 回答 3

3

认为这可能是您需要的

SELECT DISTINCT orders_id FROM orders ord
LEFT JOIN (SELECT DISTINCT Orders_Id
    FROM orders
    WHERE products_model  LIKE 'cc%' OR products_model LIKE 'dd%') ccDdItems
ON ccDdItems.Orders_id = ord.Orders_id
WHERE ccDdItems.Orders_Id IS NULL

正如 LittleBobbyTables 指出的那样,如果您还有 'ee'、'ff' 等,您可能希望将内部查询替换为 NOT LIKE 'aa%' AND NOT LIKE 'bb%'

于 2013-07-03T16:34:11.643 回答
2

您可以只使用LEFT JOIN;

SELECT DISTINCT(o1.orders_id) orders_id
FROM orders o1
LEFT JOIN orders o2
  ON o1.orders_id = o2.orders_id
 AND o2.products_model NOT LIKE 'aa%' 
 AND o2.products_model NOT LIKE 'bb%'
WHERE o2.orders_id IS NULL

一个用于测试的 SQLfiddle

……或者NOT IN……

SELECT DISTINCT(orders_id) orders_id
FROM orders
WHERE orders_id NOT IN
  ( SELECT orders_id FROM orders 
    WHERE products_model NOT LIKE 'aa%' 
      AND products_model NOT LIKE 'bb%')

另一个 SQLfiddle

...或NOT EXISTS...

SELECT DISTINCT(orders_id) oid
FROM orders
WHERE NOT EXISTS 
  ( SELECT 0 FROM orders o2 
    WHERE orders.orders_id = o2.orders_id 
      AND o2.products_model NOT LIKE 'aa%' 
      AND o2.products_model NOT LIKE 'bb%')

又一个 SQLfiddle

于 2013-07-03T16:41:50.773 回答
0

有一个HAVING子句的方法,但它可能有点太棘手了:

SELECT
    orders_id
  FROM orders
  GROUP BY orders_id
  HAVING COUNT(NULLIF(products_model LIKE 'aa%' OR
                      products_model LIKE 'bb%',
                      TRUE)) = 0;

诀窍的一部分是知道COUNT(<expression>)计算<expression>返回非NULL结果的行数。另一部分NULLIF(<test>, TRUE)用于返回isNULL的任何行。<test>TRUE

在这种情况下,我们有效地要求具有与测试orders_id不匹配的零条目的订单的值。products_model LIKE ...

这是一个你可以用来玩弄它的 SQLFiddle 。

与 Joachim Isaksson 提供的版本相比,此版本的潜在回报是,没有任何子查询或连接,查询计划更简单,因此性能可能更好。但是,对于所有性能参数,YMMV 和您应该在考虑之前使用实际数据进行测量。任何性能提升都可能不值得为棘手的维护成本付出代价。

于 2013-07-03T17:26:19.503 回答