I Must to tabels表 A
id | title | content
表 B
id | id_from_table_a | user_id | already_seen
我找不到对mysql的良好查询,它将显示如下内容:
show all from table A whitout where user_id='user_logged_id' and already_seen='yes'
上面的伪代码
这是一个大数据库,所以加入可能是一个更好的解决方案。
这是在没有连接的情况下完成的:
select * from tableA where id not in
(select id_from_table_a from tableB where user_id='user_logged_id' and already_seen='yes')
或加入:
select a.id, a.tittle, a.content from tableA a left join tableB b
on a.id = b.id_from_table_a
where b.user_id <> 'user_logged_id' and b.already_seen <> 'yes'
group by a.id, a.tittle, a.content
不确定whitout
是什么意思,但您可以根据拼写错误更改查询。 我相信这样的东西就是你要找的吗?
SELECT * FROM TableA as a
JOIN TableB as b ON a.id = b.id_from_table_a
WHERE
b.user_id = 'user_logged_in' AND b.already_seen = 'yes';
这就是我连接 2 张表的方式
SELECT * FROM TableA
INNER JOIN TableB on TableA.id=TableB.id_from_table_a
and TableB.user_id='user_logged_id'
and TableB.already_seen='yes'
SELECT * FROM tableA
JOIN TableB
ON tableA.id = TableB.tableA-id
WHERE already-seen = "yes" AND user-id != :user-logged-id
使用反联接模式返回指定结果的查询示例:
SELECT a.id
, a.title
, a.content
FROM table_a a
LEFT
JOIN table_b b
ON b.id_from_table_a = a.id
AND b.already_seen = 'yes'
AND b.user_id = 'user_logged_in'
WHERE b.already_seen IS NULL
让我们稍微展开一下。
我们返回table_a中的所有行,以及table_b中的"匹配"行。要被视为"匹配",行必须满足 ON 子句中的谓词(id_from_table_a
列必须匹配,already_seen
列和user_id
列必须满足条件。
LEFT JOIN
是外连接。它返回左侧表中的所有行(满足 WHERE 子句中的谓词),并从右侧的表中返回匹配的行。(在普通内部联接中,将排除table_a中没有来自table_b的匹配行的行。使用外部连接,将返回没有匹配项的行。
"诀窍"是排除具有匹配项的行。我们在这里使用WHERE
子句中的谓词(条件)来做到这一点。我们正在测试一列,我们知道该列在匹配行上将是非 NULL。(table_b 中的任何匹配行都将具有already_seen
列的非 NULL 值,我们保证通过 ON
子句中的条件...对于already_seen列,匹配的行的值均为 'yes'
。(我们可以引用table_b中保证为非空的任何列......如果 table_b 中的 id
列被定义为 NOT NULL 或是主键,我们可以使用它。
对于table_a
中没有匹配行的行,我们知道already_seen
列将被NULL
。因此,我们排除所有匹配的行,只保留不匹配的行table_a行。
随访
问:这种反连接是否会比正常情况下产生更快的结果,b.user_id <>"user_logged_id"和b.already_seen <>"是"? – 彩色达内特 5分钟前
答:反联接将给出与检查table_b列的不等于条件的查询不同的结果。这些测试会否定LEFT JOIN
的"外在性",使其等同于INNER JOIN
。反联接模式将返回指定的结果,即table_b中没有"匹配"行的table_a行。
就性能而言,反联接通常是最有效的,尽管其他查询模式也可以同样快。(对于返回相同结果的其他一些查询模式,执行计划是相同的。其他语句可以有不同的执行计划,这些计划通常较慢,但在某些情况下,它们实际上更快。
作为另外两种模式的示例,NOT IN
谓词...(请注意,我们需要保证子查询返回的集合中不包含NULL
值。
SELECT a.id
, a.title
, a.content
FROM table_a a
WHERE a.id NOT IN
( SELECT b.id_from_table_a
FROM table_b b
WHERE b.already_seen = 'yes'
AND b.user_id = 'user_logged_in'
AND b.id_from_table_a IS NOT NULL
)
为了完整起见,返回等效结果的NOT EXISTS
相关子查询模式的示例:
SELECT a.id
, a.title
, a.content
FROM table_a a
WHERE NOT EXISTS
( SELECT 1
FROM table_b b
WHERE b.already_seen = 'yes'
AND b.user_id = 'user_logged_in'
AND b.id_from_table_a = a.id
)
您可以查看 EXPLAIN SELECT ...
的输出以查看每个语句的实际执行计划。根据 MySQL 的版本,执行计划可能相同,也可能不同。"优化器"(MySQL代码中负责将SQL文本转换为执行计划的部分)在某些主要版本中进行了一些重大更改。