MySQL 从具有重复引用条目的联合表中选择唯一记录
Posted
技术标签:
【中文标题】MySQL 从具有重复引用条目的联合表中选择唯一记录【英文标题】:MySQL select unique record from a joint table that have duplicated referencing entry 【发布时间】: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 |
【问题讨论】:
【参考方案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 1
的NID
,然后从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
可能会很有启发性。以上是关于MySQL 从具有重复引用条目的联合表中选择唯一记录的主要内容,如果未能解决你的问题,请参考以下文章
mysql php从2个表中选择字段,具有相同的字段名称[重复]