我正在寻找解决方案,以便可以检查其他表中的不匹配项。
基本上我有3张桌子(见下文)。在这里,我要查看表1,并确定第一行在“名称”或“位置”中均不匹配。如果两者都被识别,则应移至下一行并进行检查。
我试图用SQL来完成此任务并遍历它们,但是由于我只希望第一行不匹配,所以我没有找到一个平滑的解决方案(或者正因为如此,我很新手-ish)。
我很确定这可以通过SQL来完成。
表1
Id Name Location
1 John Canada
2 James Brazil
3 Jim Hungary
表2-公认的名称
Id Name
1 John
2 James
表3-可以识别的位置
Id Location
1 Brazil
2 Hungary
所以我想从表1中进行选择,其中“名称”在表2中找不到匹配项,或者“位置”在表3中找不到匹配项。
在上面的示例中,结果应为Id = 1,因为“位置”不在表3中。
谢谢。
答案 0 :(得分:2)
您可以使用not exists
来选择是否某些子查询未选择行:
select
*
from
Table1 t1
where
not exists (
select * from Table2 t2 where t2.`Name` = t1.`Name`
) and
not exists (
select * from Table3 t3 where t3.`Location` = t1.`Location`
)
order by
t1.Id
limit 1
这不是一个非常复杂的查询,但是仍然有一些事情在进行,因此这里还是相同的,但是带有注释以解释各个部分:
select
/* I select all columns, *, for the example, but in real life scenarios
it's always better to explicitly specify which columns you need. */
*
from
/* Optionally, you can specify a short or different alias for a table (t1)
this can be helpful to make your query more readable by allowing you to explicitly
specify where a column is coming from, without cluttering the query with long names. */
Table1 t1
where
/* exists takes a sub-query, which is executed for each row of the main query.
The expression returns true if the subquery returns a row.
With not (not exists), the expression is inversed: true becomes false. */
not exists (
/* In MariaDB, backticks can be used to escape identifiers that also are
reserved words. You are allowed to use them for any identifier, but
for reserved word identifiers, they are often necessary. */
select * from Table2 t2 where t2.`Name` = t1.`Name`
)
/* Combine the two subqueries. We only want rows don't have a matching row
in sub-query one, and neither in sub-query two. */
and
not exists (
select * from Table3 t3 where t3.`Location` = t1.`Location`
)
/* Specify _some_ ordering by which you can distinguish 'first' from 'second'. */
order by
t1.Id
/* Return only 1 row (the first according to the order clause) */
limit 1