【问题标题】:Mysql : How to find non duplicate rows with left join?Mysql:如何使用左连接查找不重复的行?
【发布时间】:2016-05-28 21:04:05
【问题描述】:

几天前我在 Mysql 中遇到了一个问题,我无法解决(我对 DB 很不好),希望你能帮助我 :) 我将简化问题,以便您了解我遇到的问题!

我有两张桌子:

current_stock (article_id, ...)
stock_record (id, article_id)

Current_stock 描述实际库存,stock_record 描述已经盘点的物品。

当我想将文章留在库存中(那些在 current_stock 中但不在 stock_record 中的),以及当我得到多个相同的文章时,问题就出现了

我试过了:

SELECT * 
FROM current_stock 
WHERE NOT EXISTS (
SELECT * FROM stock_record)

还有其他形式,例如:

SELECT *
FROM current_stock
LEFT JOIN (SELECT * FROM stock_record) second
WHERE second.article_id IS NULL

但是,当 current_stock 中有多行具有相同的 article_id 时,并且在 stock_record 中有一行具有此 article_id 时,我没有得到好的结果!

例如:

current_stock (article_id)
8315
8315
8315

stock_record (id, article_id)
15, 8315

我希望结果有两行,article_id 为 8315!

(对不起,我的英语不好,希望你们能理解我!)

编辑:

使用这些表格,我在结果中一无所获,因为“不存在”或“左连接”排除了 current_stock 中带有此 article_id 的所有行。

我只想排除 stock_record 中的行数

例如:

我的 current_stock 中有 10 篇文章(article_id = 8315)
我的 stock_record 中已经扫描了 3 篇文章(article_id = 8315)

我希望结果有 7 行 this article_id。

【问题讨论】:

  • current_stockarticle_id = 8315 的三个记录有什么区别?我的意思是,你怎么能说这两个是好的,第三个是坏的?
  • 如果您在 current_stock 上有多个项目,我认为您需要在两个表中都有一个 line_item id(唯一)来识别 stock_record 中存在哪些项目。
  • 我不需要告诉哪个是好的,我只需要在结果中返回具有此 ID 的大量行。 nrResult = nrCurrentStock - nrStockRecord 对于同一篇文章_id
  • @DorianP。所以你只是在找一个号码? ,我的意思不是那个 article_id 的整行? ,在您的示例中,您想要的是数字 2 之类的东西吗?因为这是 current_stock 中该 id 的可用计数?
  • 请检查我的回答。我认为它可以满足您的需求。

标签: mysql sql database join exists


【解决方案1】:

您可以使用变量来枚举记录。然后加入行号并忽略在stock_record 中匹配的行:

SELECT t1.*
FROM (
  SELECT *, 
         @rn1 := IF(@aid = article_id, @rn1 + 1,
                    IF(@aid := article_id, 1, 1)) AS rn1
  FROM current_stock 
  CROSS JOIN (SELECT @rn1 := 0, @aid := 0) AS vars
  ORDER BY article_id) AS t1
LEFT JOIN (
  SELECT article_id, 
         @rn2 := IF(@aid = article_id, @rn2 + 1,
                    IF(@aid := article_id, 1, 1)) AS rn2
  FROM stock_record 
  CROSS JOIN (SELECT @rn2 := 0, @aid := 0) AS vars
  ORDER BY article_id
) AS t2 ON t1.article_id = t2.article_id AND t1.rn1 = t2.rn2
WHERE t2.article_id IS NULL

【讨论】:

  • 非常感谢,你是神!
【解决方案2】:

您正确的 exists() 查询:

SELECT * 
FROM current_stock t
WHERE NOT EXISTS (SELECT * FROM stock_record s
                   where t.article_id = s.article_id)

您查询中的问题,您需要检查stock_record 中是否不存在特定 id,而不是如果那里不存在任何id。

还有你正确的左连接查询:

SELECT *
FROM current_stock s
LEFT JOIN stock_record t on( t.article_id = s.article_id)
WHERE t.id IS NULL

您的左连接查询的问题在于您没有指定关系条件(请参阅 ON()),因此它不知道要连接到哪一行。

您也可以像这样使用 NOT IN:

SELECT *
FROM current_stock t
WHERE article_id NOT IN(SELECT article_id FROM stock_record)

【讨论】:

  • 是的,其实我按照你说的做了,但是这组结果并不是我所期望的。我需要“计算”article_id 的出现次数。
  • 我认为这将与 OP 中的查询给出相同的结果,因为您使用的是 article_id。
  • @DorianP。是什么给了你错误的结果?那些查询很好.. japongskie 你是什么意思?
  • 我还添加了一个 NOT IN 解决方案
  • 我期望的结果是一组包含 n 行的行,其中包含此 article_id,其中:n = 此 article_id 的当前股票行数 MINUS 具有此 article_id 的 stock_record 行数是可能吗?
【解决方案3】:

尝试按 current_stock 分组

This link 会帮助你

【讨论】:

    猜你喜欢
    • 2011-12-22
    • 2017-08-22
    • 1970-01-01
    • 1970-01-01
    • 2014-02-04
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    • 1970-01-01
    相关资源
    最近更新 更多