【问题标题】:MySQL select unique record from a joint table that have duplicated referencing entryMySQL 从具有重复引用条目的联合表中选择唯一记录
【发布时间】:2014-06-23 18:04:32
【问题描述】:

如何显示当前与第二个表中的结果不匹配的表中的所有内容。

例如:我想在(表 A)中显示当前没有类型 1 记录的每个名称。请注意,“Ken”当前有两个日志条目。类型 1 和类型 2 各一个。结果应该只显示 John 和 Genius

表 A - 名称

+-----+--------+
| nid |  name  |
+-----+--------+
|   1 |    ken |
|   2 |   john |
|   3 | genius |
+-----+--------+

表 B - 日志(每个名称可能有多个条目)

+------+-----+
| type | nid |
+------+-----+
|    1 |   1 |
|    2 |   1 |
|    2 |   2 |
+------+-----+

预期结果

| nid |  name  |
+-----+--------+
|   2 |   john |
|   3 | genius |

【问题讨论】:

    标签: mysql sql database-design relational-database


    【解决方案1】:

    您所要做的就是对子查询中 type='1' 的记录进行排序

    SELECT NAME FROM TABLEA WHERE NID NOT IN (SELECT NID FROM TABLEB WHERE TYPE='1')
    

    【讨论】:

    • 可能解决了我的问题。检查它。我不熟悉将列与 NOT IN 函数进行比较:D
    • @Ken:希望对您有所帮助。这是最简单的开始方式。
    【解决方案2】:
    SELECT nid, name from tableA 
     inner join tableB on tableA.nid = tableB.nid
     where nid > 1
    

    【讨论】:

    • 这看起来会选择除nid = 1 之外的每个用户,如果他们在表 B 中有 any 记录。它不按类型过滤。
    【解决方案3】:

    SQL Fiddle Example

    SELECT * 
    FROM TableA a
    WHERE NOT EXISTS (SELECT * FROM TableB b WHERE a.nid = b.nid AND b.type = 1) 
    

    【讨论】:

    • NOT EXIST 会比NOT IN 工作得更好吗?是否有任何理由需要匹配两个表中的值?似乎@VJHil 只是建议拉出正在使用TYPE 1NID,然后从TABLE A 中选择那些NID 不存在的地方。
    • @Ken:这完全等同于 VJHil 的 IN 子句。 EXISTS 的思想是:对于 TableA 中的每条记录,检查 TableB 中是否存在适当的记录。 IN 的想法是:从 TableB 中获取所有适当的 ID,然后从 TableA 中仅选择匹配的记录。在这两种情况下,您都将 TableA.nid 与 TableB.nid 进行比较。在 MySQL 中,EXISTS 子句通常比 IN 子句快。此外,IN 子句仅适用于 MySQL 中的一列(本例中为 nid)。但我同意,出于可读性考虑,我通常也更喜欢 IN 子句。
    【解决方案4】:

    您也许可以使用左连接...

    SELECT a.nid, a.name
    FROM tableA a
    LEFT JOIN tableB b ON a.nid = b.nid AND b.type = 1
    WHERE b.nid IS NULL
    

    基本上,如果查询在表 B 中找不到满足连接条件的记录,它将连接一行全为空的。

    【讨论】:

    • 似乎也能正常工作,但@VJHil 方法似乎更干净。这会更有效吗?
    • @Ken:不确定。一个体面的 DBMS 应该对两者几乎一视同仁。我已经看到 MySQL 在这方面做得不够好,但是对于这么简单的查询,它应该知道运行一次子选择。每个查询上的 EXPLAIN 可能会很有启发性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 2023-03-27
    • 1970-01-01
    • 2020-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多