【问题标题】:MYSQL: UNION results between two tables where omitting records from first table if PK found in second tableMYSQL:两个表之间的 UNION 结果,如果在第二个表中找到 PK,则省略第一个表中的记录
【发布时间】:2018-11-09 00:04:43
【问题描述】:

我有两张表 productsproduct_edits 保存价格表上的产品信息。我的应用程序的工作方式是,如果用户更改 products 表中的任何产品信息,它会将其插入到 product_edits 表中......

产品表

pk|code|name     |description|price|....
-----------------------------------
1 |QW1X|Product 1|...
2 |LW1X|Product 2|...
3 |DE1X|Product 3|...

PRODUCT_EDITS 表

pk|product_id|code|name              |description|price|....
-----------------------------------
1 |         2|LW1X|Product 2 new name|...

在上述情况下,我想要一个从两个表中返回记录的 SQL,但如果在 product_edits 表中找到产品,它只会从 product_edits 中选择,而不是从 products 表中选择。

我尝试使用标准联合但从两个表中选择所有记录:

select code, name, description from products
union
select code, name, description from product_edits

【问题讨论】:

  • 您是否在该表中保留了多个产品编辑 - 即,如果您将 LW1X 更新为“产品 2 新名称”,那么您会在 product_edits 中有两条记录,还是只有一条?如果是后者,我会问重点是什么(为什么不只是更新产品?),如果是前者,您将需要处理您的子选择。

标签: mysql sql union


【解决方案1】:

在这种情况下,最好使用EXISTS 而不是IN。 您希望在找到匹配项后停止搜索,而不是查看来自 product_edits 的所有结果。

所以这样做:

SELECT
    code, name, description
FROM products p
WHERE NOT EXISTS (SELECT 1 FROM product_edits e WHERE e.code = p.code)
UNION
SELECT
    code, name, description
FROM product_edits

【讨论】:

  • 是的,这是首选行为并经过优化......尽管@scubasteve623 提供的解决方案也有效
【解决方案2】:
select code, name, description from products
where code not in(select code from product_edits)
union
select code, name, description from product_edits

【讨论】:

    【解决方案3】:

    您可以使用 IFNULL 功能 http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html#function_ifnull

    如果你的表是相关的,你可以试试这样的:

    SELECT 
        p.code, IFNULL(pe.name, p.name), IFNULL(pe.description, p.description) 
    from 
        products p 
        left join product_edit pe on (p.id = pe.product_id)
    UNION
    SELECT 
        pe2.code, pe2.name, pe2.description
    from 
        product_edits pe2
    

    第一部分将为您提供仅在 products 表中的产品以及在两个表中但带有 product_edits.description 的产品。

    第二部分会给你只在 products_edits 表中的产品,因为联合会删除重复的记录

    【讨论】:

    • 这不起作用,仍然从两个表中选择行
    • 好吧,我搞错了。变化的列名。因此,IFNULL 应该应用于该列,而不是描述(或者如果描述和名称不同,则两个列)。
    • 这里重要的是在联合的两个部分返回相等记录的概念。我很抱歉这个错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-05
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 2013-10-05
    相关资源
    最近更新 更多