我正在对数据库应用程序进行一些维护工作,并且我发现,欢乐的乐趣,即使来自一个表的值正在使用外键的样式,表上没有外键约束。
我正在尝试在这些列上添加FK约束,但我发现,因为表中的错误数据已经完全加载了之前已经被天真校正的错误,我需要找到哪些行不匹配另一个表然后删除它们。
我在网上找到了一些这类查询的例子,但它们似乎都提供了示例而不是解释,我不明白它们为什么会起作用。
有人可以向我解释如何构建一个查询,该查询返回在另一个表中没有匹配的所有行,以及它正在做什么,以便我可以自己进行这些查询,而不是为此中的每个表运行到SO没有FK约束的 mess ?
答案 0 :(得分:494)
这是一个简单的查询:
SELECT t1.ID
FROM Table1 t1
LEFT JOIN Table2 t2 ON t1.ID = t2.ID
WHERE t2.ID IS NULL
关键点是:
LEFT JOIN
被使用;这将返回Table1
中的所有行,无论Table2
中是否存在匹配的行。
WHERE t2.ID IS NULL
条款;这会将返回的结果限制为仅从Table2
返回的ID为空的行 - 换句话说,Table2
中的{strong> NO 记录来自Table1
的特定ID 1}}。对于Table2.ID
中Table1
未匹配ID的所有记录,Table2
将返回NULL。
答案 1 :(得分:59)
我会使用EXISTS
表达式,因为它更强大,你可以更精确地选择你想要加入的行,如果是LEFT JOIN
你必须把连接表中的所有东西都拿走。它的效率可能与使用null测试的LEFT JOIN
的情况相同。
SELECT t1.ID
FROM Table1 t1
WHERE NOT EXISTS (SELECT t2.ID FROM Table2 t2 WHERE t1.ID = t2.ID)
答案 2 :(得分:10)
SELECT id FROM table1 WHERE foreign_key_id_column NOT IN (SELECT id FROM table2)
表1中有一列要添加外键约束,但foreign_key_id_column
中的值并不都与表2中的id
匹配。
id
。这些将是我们要删除的行。 NOT IN
子句将查询限制为仅foreign_key_id_column
中的值不在表2 id
列表中的行。 SELECT
语句将获得表2中所有id
的列表。答案 3 :(得分:7)
T2
是您要添加约束的表:
SELECT *
FROM T2
WHERE constrained_field NOT
IN (
SELECT DISTINCT t.constrained_field
FROM T2
INNER JOIN T1 t
USING ( constrained_field )
)
删除结果。
答案 4 :(得分:3)
现在我希望员工表中那些不在薪水中的记录。 我们可以用3种方式做到这一点 -
答案 5 :(得分:1)
从这里类似的问题MySQL Inner Join Query To Get Records Not Present in Other Table,我开始尝试
SELECT * FROM bigtable
LEFT JOIN smalltable ON bigtable.id = smalltable.id
WHERE smalltable.id IS NULL
smalltable
是您缺少记录的地方,bigtable
是您有所有记录的地方。该查询列出了smalltable
中不存在但在bigtable
上存在的所有记录。您可以用任何其他匹配条件替换id
。
答案 6 :(得分:0)
我不知道哪一个是优化的(与@AdaTheDev相比 )但是当我使用(至少对我来说)时,这个似乎更快
SELECT id FROM table_1 EXCEPT SELECT DISTINCT (table1_id) table1_id FROM table_2
如果您想获得任何其他特定属性,可以使用:
SELECT COUNT(*) FROM table_1 where id in (SELECT id FROM table_1 EXCEPT SELECT DISTINCT (table1_id) table1_id FROM table_2);
答案 7 :(得分:0)
您可以选择观看次数,如下所示:
CREATE VIEW AuthorizedUserProjectView AS select t1.username as username, t1.email as useremail, p.id as projectid,
(select m.role from userproject m where m.projectid = p.id and m.userid = t1.id) as role
FROM authorizeduser as t1, project as p
,然后在视图上进行选择或更新:
select * from AuthorizedUserProjectView where projectid = 49
产生如下图所示的结果,即,对于不匹配的列null已被填充。
[Result of select on the view][1]
答案 8 :(得分:-1)
SELECT * FROM First_table 减去 选择*从另一个
答案 9 :(得分:-2)
您可以执行类似的操作
SELECT IFNULL(`price`.`fPrice`,100) as fPrice,product.ProductId,ProductName
FROM `products` left join `price` ON
price.ProductId=product.ProductId AND (GeoFancingId=1 OR GeoFancingId
IS NULL) WHERE Status="Active" AND Delete="No"
答案 10 :(得分:-5)
如何在两个表中选择没有匹配条目的行?
select * from [dbo].[EmppDetails] e right join [Employee].[Gender] d on e.Gid=d.Gid where e.Gid is Null union select * from [dbo].[EmppDetails] e left join [Employee].[Gender] d on e.Gid=d.Gid where d.Gid is Null