我真的需要一些帮助来确定查询,我需要运行该查询以返回以下条件:
日期和时间字段为DATETIME
表结构
patients - id, name, call_back_date, last_service_date, finalized_date, lock_status
queues - id, name, home_user_id, active
1, test, 2, 1
patient_queue - id, queue_id, patient_id
1, 1, 1
user_queue - id, queue_id, user_id, active
1, 1, 1, 1
SELECT
pq.patient_id
FROM patient_queue pq
INNER JOIN queues q
ON pq.queue_id = q.id
INNER JOIN user_queue uq
ON uq.queue_id = q.id
INNER JOIN patients p
ON pq.patient_id = p.id
WHERE pq.queue_id = (SELECT
uq.queue_id
FROM user_queue uq
WHERE uq.active = TRUE
AND uq.user_id = 4)
AND p.lock_status = FALSE
AND p.member_status = 'Enrolled'
OR p.member_status = 'Enrollment'
AND uq.active = TRUE
AND q.active = TRUE
AND p.household_id = NULL
AND p.call_back_date <= NOW()
OR p.call_back_date = NULL
AND (NOW() - p.finalized_date) <= 20
AND p.finalized_date < NOW()
OR p.call_back_date = NULL
AND p.finalized_date = NULL
OR q.home_user_id = 10
AND p.call_back_date <= NOW()
OR q.home_user_id = 10
AND p.call_back_date = NULL
AND (NOW() - p.finalized_date) <= 20
AND p.finalized_date < NOW()
OR q.home_user_id = 10
AND p.call_back_date = NULL
AND p.finalized_date = NULL
ORDER BY IF(p.call_back_date < NOW(), 0, IF(ISNULL(p.last_service_date), 0.5, p.last_service_date));
我得到的结果不正确,如果刷新查询,它会像5次一样循环,所以我会得到2的ID,然后是10、5、6、32,然后返回2并重新开始,所以我不知道它是我的回叫日期还是我是否在考虑此查询或什么?
答案 0 :(得分:0)
不是一个完整的答案,但是我可以做一些可能的改进,可能会促使您提出正确的查询
SELECT pq.patient_id
FROM patient_queue pq
INNER JOIN queues q ON pq.queue_id = q.id
INNER JOIN user_queue uq ON uq.queue_id = q.id
INNER JOIN patients p ON pq.patient_id = p.id
第一个问题,我不明白为什么这需要成为子查询。删除它并在主查询中使用WHERE条件
WHERE pq.queue_id = (SELECT
uq.queue_id
FROM user_queue uq
WHERE uq.active = TRUE
AND uq.user_id = 4)
所以这代替
WHERE uq.active = TRUE
AND uq.user_id = 4
AND p.lock_status = FALSE
您在这里混合AND和OR而没有括号,这很可能是错误的
AND p.member_status = 'Enrolled'
OR p.member_status = 'Enrollment'
应写为
AND (p.member_status = 'Enrolled' OR p.member_status = 'Enrollment')
下面您再次遇到与OR相同的问题,但是我很难理解如何对它们进行分组,但是由于您多次使用OR p.call_back_date = NULL
和OR q.home_user_id = 10
,因此很明显您需要使用括号
AND uq.active = TRUE
AND q.active = TRUE
AND p.household_id = NULL
AND p.call_back_date <= NOW()
OR p.call_back_date = NULL
AND (NOW() - p.finalized_date) <= 20
AND p.finalized_date < NOW()
OR p.call_back_date = NULL
AND p.finalized_date = NULL
OR q.home_user_id = 10
AND p.call_back_date <= NOW()
OR q.home_user_id = 10
AND p.call_back_date = NULL
AND (NOW() - p.finalized_date) <= 20
AND p.finalized_date < NOW()
OR q.home_user_id = 10
AND p.call_back_date = NULL
AND p.finalized_date = NULL
ORDER BY IF(p.call_back_date < NOW(), 0, IF(ISNULL(p.last_service_date), 0.5, p.last_service_date));
可能相关,但是请注意,NOW()也包含一个时间,因此取决于日期列中存储的内容与NOW()进行比较可能无法按预期工作。
答案 1 :(得分:0)
日期算术是错误的:
(NOW() - p.finalized_date) <= 20
->
p.finalized_date >= NOW() - INTERVAL 20 DAY
或(仅用于交谈日期,而不是日期时间):
p.finalized_date >= CURDATE() - INTERVAL 20 DAY
同时,这可以:
p.call_back_date <= NOW() -- meaning that the callback dates is at or before this instant.
AND与OR
a AND b OR c AND d means (a AND b) OR (c AND d)
如果您要
a AND (b OR c) AND d
然后必须使用括号。显然,这里需要这样做:
AND p.call_back_date <= NOW()
OR p.call_back_date = NULL
AND ...
->
AND (p.call_back_date <= NOW() OR p.call_back_date = NULL)
AND ...
IN()-为清楚起见,请更改
AND (p.member_status = 'Enrolled' OR p.member_status = 'Enrollment')
到
AND p.member_status IN ('Enrolled', 'Enrollment')
(性能没有差异,等等)