MySQL查询从表2中选择行,如果表1中的* all *行不存在

时间:2015-09-04 15:03:15

标签: mysql join

我正在做一种销售点系统,其MySQL数据库(除其他外)有一个带有待售物品的桌子,一张带销售的桌子和一张带有购买的桌子(购买是我的特设)对于在销售中购买的任何单个商品的符号;如果同一个人一次购买三件商品,例如,这是一次销售,包括三次购买)。所有这些表都有逻辑ID,即。 item_idsale_idpurchase_id,可轻松加入简单的关键表格。

我现在正在尝试添加折扣功能;基本上你的花园品种超市折扣:购买这些特殊项目并支付X而不是支付正常项目价格的全部金额。这些“套餐优惠”有自己的表格,并通过包含itemsdeal_id的简单关键表与item_id表相关联。

我的问题是要弄清楚何时应用这个问题。举几个例子:

items
+---------+--------+---------+
| item_id | title  | price   |
+---------+--------+---------+
|      12 | Shoe   |      10 |
|      76 | Coat   |      23 |
|      82 | Whip   |      19 |
+---------+--------+---------+

sales
+---------+-----------+
| sale_id | timestamp |
+---------+-----------+
|    2973 | 144995839 |
|    3092 | 144996173 |
+---------+-----------+

purchases
+-------------+-------------+---------+----------+---------+
| purchase_id | no_of_items | item_id | at_price | sale_id |
+-------------+-------------+---------+----------+---------+
|       12993 |           1 |      12 |       10 |    2973 |
|       12994 |           1 |      76 |       23 |    2973 |
|       12996 |           1 |      82 |       19 |    2973 |
|       13053 |           1 |      12 |       10 |    3092 |
|       13054 |           1 |      82 |       19 |    3092 |
+-------------+-------------+---------+----------+---------+

package_deals
+---------+-------+
| deal_id | price |
+---------+-------+
|       1 |    40 |
+---------+-------+

deals_items
+---------+---------+
| deal_id | item_id |
+---------+---------+
|       1 |      12 |
|       1 |      76 |
|       1 |      82 |
+---------+---------+

从中可以明显看出,我们的鞋子价格为10美元(我们假设我们在这里使用美元作为我们的货币,无所谓),一件价值23美元的外套,以及一件价值19美元的鞭子。我们还有一揽子协议,如果你同时购买一双鞋,一件外套和一条鞭子,你可以获得40美元的全部费用。

在给出的两个销售中,一个(2973)已经购买了所有三件商品并且将获得折扣,而另一个(3092)仅购买鞋子和鞭子并且不会获得折扣。

为了确定是否应用套餐优惠,我当然必须找出套餐优惠中的所有 item_id是否存在于给定purchases的{​​{1}}表。

我该怎么做?

我以为我应该可以做这样的事情:

sale_id

在我的脑海中,它检索了SELECT deal_id, item_id, purchase_id FROM package_deals LEFT JOIN deals_items USING (deal_id) LEFT JOIN purchases USING (item_id) WHERE sale_id = 2973 AND item_id IS NULL GROUP BY deal_id 表中的所有行,其中至少有一个package_deal与相关的包处理相关联的item_id中没有相应的匹配给出purchases的表。然后,这会告诉我哪些包适用;即,它将为购买2973返回零行(因为在sale_id上过滤的purchases表中没有与包交易1相关的项目,而在3092中没有一行(因为其中一项)与套餐交易相关联 - 即外套,sale_id = 2973 76-在item_id过滤的purchases表格中不存在。

显然,它没有做我天真以为的那样 - 相反,它总是返回零行,无论如何。

对于我而言,对于应该应用的每个包交易,结果集是否为我提供了一行,或者不应该的每个包交易一行,这对我来说并不重要。 em> apply-but 如何让它在单个查询中显示?

甚至可能吗?

1 个答案:

答案 0 :(得分:2)

上面的查询存在的问题是,由于LEFT JOIN,sale_id在您感兴趣的缺失行中也为NULL。

对于不适用于给定订单的任何交易,此查询将返回deal_id

SELECT DISTINCT
            pd.deal_id
FROM        package_deals pd
JOIN        deals_items di on pd.deal_id = di.deal_id
WHERE       di.item_id NOT IN (SELECT item_id FROM purchases WHERE sale_id = 3092)

从中可以很容易地找出适用的那些。请注意,对于功能完备的系统,您仍需要考虑购买数量 - 例如如果客户购买了交易中的两个中的两个,但只有第三个......等等。

演示查询的SQL小提琴在这里:http://sqlfiddle.com/#!9/f2ae4/8

请注意,我使用ON语法进行了联接,因为我比USING更熟悉。如果你愿意的话,我希望这也会有用。