首先,这个问题涉及PHP和MySQL
我有两个数据库表:
People
表:
person_id | field_1 | field_2 | other_fields...
Notes
表:
note_id | person_id | created_timestamp | other_fields...
People
表与Notes
表有一对多关系...
每次在Notes
表中创建一个注释时,都会附加一个时间戳,同时也会分配person_id
个外键。
现在...
我需要找到所有people
在过去30天内没有note
对他们的人。{
我现在的方式是:
Notes
表中获取具有不同person_id
和created_timestamp
>的所有备注'time(31*86400)'
(不准确......我知道,但适合我的需要)person_id
添加到临时数组$temp
People
表格in_array()
与person_id
$temp
比较
醇>
当有很多People
或Notes
时,这不是非常有效并且使应用程序瘫痪。
有没有人有更好的解决方案。理想情况下,只需一个SQL查询即可实现。
感谢您寻找
答案 0 :(得分:2)
SELECT person_id FROM People WHERE person_id NOT IN
(SELECT person_id FROM Note
WHERE created_timestamp > DATE_SUB(CURDATE(), INTERVAL 30 DAY))
这假定create_timestamp的类型为“DATE”,“TIMESTAMP”或“DATETIME”。如果您使用unix时间戳,请使用FROM_UNIXTIME(created_timestamp)
答案 1 :(得分:1)
标准解决方案是使用此表单的子查询:
Select * from people where PersonID NOT in
(select PersonID from Notes where Created_Timestamp>...)
另一个选项是在Notes上执行右外连接,仅针对Notes.PersonID IS NULL进行过滤,它仅为您提供Notes上不匹配的行。
就我个人而言,我更喜欢上面的子查询方法,该方法应该比外连接解决方案运行得更高效,更容易理解。
答案 2 :(得分:1)
我相信这应该有效:
SELECT * FROM people WHERE person_id NOT IN(SELECT DISTINCT person_id FROM notes);
答案 3 :(得分:1)
如果这很关键,您可以考虑非规范化:将最后一个音符的时间戳存储在用户表中,并为该列编制索引。
否则,没有办法避免遍历整个人员表,所以在note表的(person_id,timestamp)对上添加索引并使用左连接或子查询:
SELECT * FROM people
LEFT JOIN notes ON people.person_id = notes.person_id
AND notes.created_timestamp < NOW() - INTERVAL 30 DAY
WHERE notes.person_id IS NULL
SELECT * FROM people
WHERE person_id NOT IN (SELECT person_id FROM notes
WHERE created_timestamp < NOW() - INTERVAL 30 DAY)
答案 4 :(得分:1)
SELECT p.*
FROM PEOPLE p
LEFT JOIN NOTES n ON n.person_id = p.person_id
AND n.created_timestamp >= DATE_SUB(NOW(), INTERVAL 30 DAY)
WHERE n.note_id IS NULL
SELECT p.*
FROM PEOPLE p
WHERE NOT EXISTS(SELECT NULL
FROM NOTES n
WHERE n.person_id = p.person_id
AND n.created_timestamp >= DATE_SUB(NOW(), INTERVAL 30 DAY))
SELECT p.*
FROM PEOPLE p
WHERE p.person_id NOT (SELECT n.person_id
FROM NOTES n
WHERE n.created_timestamp >= DATE_SUB(NOW(), INTERVAL 30 DAY))
LEFT JOIN IS NULL is the most efficient on MySQL when the columns compared are not nullable。如果是the columns compared were nullable, NOT IN and NOT EXISTS are more efficient。