Php 从另一个数据库的2个字段中选择不存在的2条数据库记录
我想从数据库'items'中提取两条记录,限制2,这些记录在'fA'或'fB'字段的'item_matches'中不同时存在Php 从另一个数据库的2个字段中选择不存在的2条数据库记录,php,mysql,Php,Mysql,我想从数据库'items'中提取两条记录,限制2,这些记录在'fA'或'fB'字段的'item_matches'中不同时存在 item_matches +------+------+ | fA | fB | +------+------+ | abc | roc | | def | pod | | ghi | his | | 4 | 6 | | 5 | | +-----
item_matches
+------+------+
| fA | fB |
+------+------+
| abc | roc |
| def | pod |
| ghi | his |
| 4 | 6 |
| 5 | |
+------+------+
+------+
| items|
+------+
| abc |
| def |
| ghi |
| roc |
| pop |
| blr |
| doc |
+------+
这是一个查询的结果:
未选择abc和roc
未选择roc和abc
选择ghi和roc
另一个问题
未选择def和pod
ghi和his未被选中
doc和pod selected这里的一种方法是对items表进行交叉连接以生成所有对,然后根据item_matches表左连接以检查不完全匹配的对。这里的逻辑是,如果联接列fA或fB中的任何一个为null,则意味着找不到该对的精确匹配
SELECT i.item1, i.item2
FROM
(
SELECT t1.BAND AS item1, t2.BAND AS item2
FROM items t1
INNER JOIN items t2
ON t1.BAND <> t2.BAND
WHERE t1.active = 1 AND t2.active = 1
) i
LEFT JOIN item_matches im
ON i.item1 = im.fA AND
i.item2 = im.fB
WHERE
im.fA IS NULL OR im.fB IS NULL
ORDER BY RAND()
LIMIT 2;
我选择在上面的查询中使用随机排序,但您可能想更改它。在任何情况下,在不提供排序的情况下对结果集使用LIMIT通常没有多大意义,因为您还没有告诉数据库要保留哪2条记录
一种可能的方法是使用反连接模式
SELECT a.colname
, b.colname
FROM items a
JOIN items b
ON NOT ( a.colname <=> b.colname )
LEFT
JOIN item_matches m
ON m.fA = a.colname
AND m.fB = b.colname
LEFT
JOIN item_matches o
ON o.fA = b.colname
AND o.fB = a.colname
WHERE m.fA IS NULL
AND o.fA IS NULL
ORDER BY NULL
LIMIT 2
+10.我读到规范要求检查匹配项fB、fA以及fA、fB,可能我想得太多了,这个答案中的查询将work@spencer7593我见过你两次加入,不知道为什么。让我们看看OP有什么要说的。我做了两次反连接以避免性能降低或a=fA和b=fB或a=fB和b=fA这对我来说是有效的,但对带有2111条记录的项目_matches db运行查询需要1517897065.7022778988秒!这是一个开销很高的查询吗?@BillStig性能不佳的原因可能是我需要从items表生成所有可能的对,而items表只列出单个值。能否生成包含所有对的表?如果是这样,那么查询应该执行得更快。你们也可以试试斯宾塞的答案,若这比我的答案快的话。仍然在测试这个,只返回1个项目而不是2个,但当order by更改为rand时,查询时间非常长;按RAND排序需要MySQL生成整个结果集,本质上是与每个项匹配的每个项的叉积,不包括那些具有匹配项的对,然后对集合中的每一行计算RAND函数,然后对整个集合执行排序操作。完成后,我们可以返回几行。我没有按兰德公司订货是有原因的。对于大型集合,我们需要确保有合适的索引可用。此答案中的SQL FIDLE演示链接包括适当索引的定义。