MariaDB结果集未返回正确结果

时间:2019-02-06 04:51:12

标签: sql join mariadb

我真的需要一些帮助来确定查询,我需要运行该查询以返回以下条件:

  • 不要将保留日期晚于今天的患者出诊
  • 除非患者甘蔗休假,否则不要向他们展示当月的“最终日期”
  • 在当月15日之前,不要为患者提供23日之后最后一个月的最终日期
  • 仅将当前患者分配到队列
  • 仅向其“家庭”用户展示“家庭患者”

日期和时间字段为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并重新开始,所以我不知道它是我的回叫日期还是我是否在考虑此查询或什么?

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 = NULLOR 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')

(性能没有差异,等等)