SQLite查询选择另一个表中不存在的所有记录
Posted
技术标签:
【中文标题】SQLite查询选择另一个表中不存在的所有记录【英文标题】:SQLite query select all records that does not exist in another table 【发布时间】:2014-07-31 01:33:25 【问题描述】:我在尝试执行 SQLite 查询以获取另一个表中不存在的记录时遇到了一些问题。基本上我有两个数据库表:
我的锻炼表存储了所有可用的锻炼,而bookedExercise 表存储了每个用户预订的锻炼。我想做的是,例如,如果练习确实存在于bookedExercise 中,则应将其过滤掉。
这是我使用的 SQLite 查询:
SELECT exercise.exerciseID, exercise.exerciseType, exercise.amout FROM exercise LEFT JOIN bookedExercise WHERE exercise.exerciseID = bookedExercise.exerciseID AND bookedExercise.exerciseID IS NULL
但是,它返回给我空记录。有任何想法吗?
提前致谢。
【问题讨论】:
【参考方案1】:如果你不使用连接没问题,你可以使用
SELECT * FROM exercise WHERE exerciseID not in (SELECT exerciseID FROM bookedExercise)
【讨论】:
+1 同样可以接受的解决方案。对于某些 DMBS 系统,in 子句中的查询对于大量值的效率低于哈希连接/反连接,但我不确定这是否适用于 SQLite。除非你在 10,000+ 范围内,否则可能没关系 @boblikepie 它有效!但是有什么方法可以增强 SQL 的性能,例如,如果预定时间大于当前日期,则不应选择它。 您可以将其包含在子查询中(来自in
子句)或仅将其包含在您最初列出的查询中 - 只需确保将连接条件放在连接子句中,而不是where 子句。
@Hambone 对不起,你介意给我看一些例子吗?因为我不确定你所说的加入条件是什么意思。因为我试图把 WHERE exerciseID not in (SELECT exerciseID FROMbookedExercise) ANDbookedTime > DATETIME('NOW') 并且它给我一个错误消息说没有这样的列bookedTime
如果你的意思是你现在只想排除那些有预定时间的人>,那么你真的很接近了。将子句保留在括号内。其中不包含运动ID(从bookedExercise 中选择运动ID,其中bookedTime > DATETIME('NOW'))。【参考方案2】:
使用LEFT JOIN时,必须将连接条件放入ON子句中:
SELECT exercise.exerciseID,
exercise.exerciseType,
exercise.amout
FROM exercise /* !! */
LEFT JOIN bookedExercise ON exercise.exerciseID = bookedExercise.exerciseID
WHERE bookedExercise.exerciseID IS NULL
【讨论】:
【参考方案3】:您的 SQL 看起来不错...我认为问题可能是您的数据类型不匹配。您在一个表格中将锻炼 ID 作为整数,在另一个表格中有文本。
另外,如果您有大量数据,您可能需要考虑反连接:
select
e.*
from
exercise e
where not exists (
select 1
from bookedExercise be
where
e.excerciseId = be.exerciseID
)
-- 编辑--
再看一眼,您的 SQL 不正常。您在 where 子句中有加入条件。这个小改动将修复您现有的 SQL:
SELECT exercise.excerciseId , exercise.exerciseType , exercise.amout
FROM exercise LEFT JOIN bookedExercise on
exercise.excerciseId = bookedExercise.exerciseID
WHERE bookedExercise.exerciseID IS NULL
【讨论】:
以上是关于SQLite查询选择另一个表中不存在的所有记录的主要内容,如果未能解决你的问题,请参考以下文章
从一个表中选择 Laravel 5.1 中另一个表中不存在的所有记录