如何在多个表上加入多个条件

时间:2011-09-07 21:27:48

标签: mysql join

我正在编写一个能够检查同一用户的多行的查询。如果相同用户记录的组合未提供我需要的所需信息,(记住它是用户拥有的所有记录的组合,而不是单个记录的组合),则认为用户已通过。

例如:有两个表。

一个是保留用户个人信息的“用户”:

id client_id first_name last_name date_of_birth ssn address

另一个是“筛选”,用于保存用户的医疗测试信息:

id user_id date cholesterol ldl hemoglobin triglycerides mcv glucose 
mchc ha1c plateletcount.

一个用户在用户表中只能有一条记录,但筛选表中可能有多条记录。我想要做的是检查属于同一用户的用户的多个筛选记录,看看这些记录的组合是否提供了我需要的必要信息。如果否,则选择用户。例如,必要的信息包括胆固醇,ldl,甘油三酯,葡萄糖或。如果用户有两个筛选记录,则一个记录提供cholesterol(NOT NULL),另一个记录提供triglycerides(NOT NULL)glucose(NOT NULL)ha1c(NOT NULL)。他被选中是因为ldl失踪了。

如何编写能够执行此操作的查询?我尝试了内连接,但它似乎不起作用。这里有一些要求。对于胆固醇,ldl和甘油三酯,只要其中一个缺失,就应该选择用户。但对于葡萄糖和ha1c,只有当两者都缺失时才会选择用户。

我试过的一个问题是这样的:

   SELECT users.id AS user_id, users.first_name, users.last_name, clients.name AS client, 
       users.social_security_number AS ssn, users.hiredate, hra.id AS hra_id, hra.date             AS hra_date, hra.maileddate AS hra_maileddate, 
            screening.id AS screening_id, screening.date AS screening_date,         screening.maileddate AS screening_maileddate
        FROM users 
        INNER JOIN clients
        ON(
           users.client_id = clients.id
           )
        INNER JOIN hra
        ON(
           users.id = hra.user_id
           )
        LEFT JOIN screening
        ON(
           users.id = screening.user_id
          )
        WHERE users.client_id = '1879'      
        AND hra.date BETWEEN '2011-07-01' AND '2011-11-15'
        AND hra.maileddate IS NOT NULL 
        AND screening.date BETWEEN '2011-05-15' AND '2011-11-15'
        AND screening.maileddate IS NULL    
        AND screening.cholesterol IS NOT NULL
        AND screening.ldl IS NOT NULL
        AND screening.triglycerides IS NOT NULL
        AND (screening.glucose IS NOT NULL OR screening.ha1c IS NOT NULL)
        GROUP BY users.id

什么是正确的查询?

3 个答案:

答案 0 :(得分:0)

只需将针对实验室的条件从WHERE移至ON

    ......
    LEFT JOIN labs
    ON(
       users.id = labs.user_id
       AND labs.date BETWEEN '2011-05-15' AND '2011-11-15'
       AND labs.maileddate IS NULL    
       AND labs.cholesterol IS NOT NULL
       AND labs.ldl IS NOT NULL
       AND labs.triglycerides IS NOT NULL
       AND (labs.glucose IS NOT NULL OR labs.ha1c IS NOT NULL)
      )
    WHERE users.client_id = '1879'      
    AND hra.date BETWEEN '2011-07-01' AND '2011-11-15'
    AND hra.maileddate IS NOT NULL 

如果您需要查询返回hra中没有条目的用户,请对hra执行相同操作(不要忘记,它应该是LEFT JOIN

答案 1 :(得分:0)

好像你想要一个OR而不是AND 此外,如果您希望在缺少某些内容时选择它们,请选择“IS NULL”,而不是“IS NOT NULL”

您开始寻找拥有HRA的用户:

WHERE users.client_id = '1879'      
    AND hra.date BETWEEN '2011-07-01' AND '2011-11-15'

//然后你似乎想要这样的东西:

AND(  labs.cholesterol IS NULL
OR  labs.ldl IS NULL
OR labs.triglycerides IS NULL
OR (labs.glucose IS NULL AND labs.ha1c IS NULL))

答案 2 :(得分:0)

通过在WHERE子句中检查NOT NULL,你破坏了LEFT JOIN的目的,实质上是将它变成INNER JOIN ......

SELECT users.id AS user_id, users.first_name, users.last_name, clients.name AS client, 
       users.social_security_number AS ssn, users.hiredate, hra.id AS hra_id, 
       hra.date AS hra_date, hra.maileddate AS hra_maileddate, 
       screening.id AS screening_id, screening.date AS screening_date,                screening.maileddate AS screening_maileddate
FROM users 
INNER JOIN clients  ON(users.client_id = clients.id)
INNER JOIN hra ON(users.id = hra.user_id)
-- This says, find matching records in labs, and if there aren't any, then bring
-- back the fields anyway, filled will NULL's
LEFT JOIN labs ON(users.id = labs.user_id)
WHERE users.client_id = '1879'      
AND hra.date BETWEEN '2011-07-01' AND '2011-11-15'
AND hra.maileddate IS NOT NULL 
-- These in the WHERE clause defeats the purpose of the LEFT JOIN
-- Move them into the ON condition of the LEFT 
            AND labs.date BETWEEN '2011-05-15' AND '2011-11-15'
            AND labs.maileddate IS NULL    
            AND labs.cholesterol IS NOT NULL
            AND labs.ldl IS NOT NULL
            AND labs.triglycerides IS NOT NULL
            AND (labs.glucose IS NOT NULL OR labs.ha1c IS NOT NULL)
GROUP BY users.id

当LEFT JOIN找不到匹配的记录时,它会从一行中返回字段,但用NULL填充它们的值。