如何查询多行组合(MySQL)

时间:2011-09-08 01:15:20

标签: mysql

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

例如:有两个表。

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

id client_id first_name last_name date_of_birth ssn address 另一个是“筛选”,用于保存用户的医疗测试信息:

id user_id date cholesterol ldl血红蛋白甘油三酯mcv葡萄糖 mchc ha1c plateletcount。 一个用户在用户表中只能有一条记录,但在筛选表中可能有多条记录。我想要做的是检查属于同一用户的用户的多个筛选记录,看看这些记录的组合是否提供了我需要的必要信息。如果否,则选择用户。例如,必要的信息包括胆固醇,ldl,甘油三酯,葡萄糖或。如果用户有两个筛选记录,一个记录提供胆固醇(NOT NULL),另一个提供甘油三酯(NOT NULL),葡萄糖(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, 
        sall.id AS screening_id, sall.date AS screening_date, sall.maileddate AS     screening_maileddate
    FROM users 
    INNER JOIN clients
    ON(
       users.client_id = clients.id
       AND users.client_id = '1879'
       )
    INNER JOIN hra
    ON(
       users.id = hra.user_id
       AND hra.date BETWEEN '2011-07-01' AND '2011-11-15'
       AND hra.maileddate IS NOT NULL 
       )
     INNER JOIN screening sall
     ON(
     sall.user_id = users.id 
     )
      INNER JOIN screening s1
      ON(
      s1.user_id = users.id

      AND s1.date BETWEEN '2011-05-15' AND '2011-11-15'
    ) 
    INNER JOIN screening s2
    ON(
       s2.user_id = users.id

      AND s2.date BETWEEN '2011-05-15' AND '2011-11-15'
    ) 
    INNER JOIN screening s3
    ON(
      s3.user_id = users.id

      AND s3.date BETWEEN '2011-05-15' AND '2011-11-15'
    )
    INNER JOIN screening s4 
    ON(
       s4.user_id = users.id

      AND s4.date BETWEEN '2011-05-15' AND '2011-11-15'
    )
    INNER JOIN screening s5
    ON(
       s5.user_id = users.id

      AND s5.date BETWEEN '2011-05-15' AND '2011-11-15'
  )
    INNER JOIN screening s6
    ON(
      s6.user_id = users.id

      AND s6.date BETWEEN '2011-05-15' AND '2011-11-15'
  )

    WHERE ((s1.cholesterol IS NULL
    OR s2.ldl IS NULL
    OR s3.triglycerides IS NULL)
    OR (s4.glucose IS NULL
    AND s5.ha1c IS NULL))
    AND s6.maileddate IS NULL
    GROUP BY users.id

2 个答案:

答案 0 :(得分:1)

你不想要内连接,你想要左连接。当任何连接条件失败时,内连接会抑制结果行,而左连接则允许结果行显示空项。

你离这儿很近。

答案 1 :(得分:1)

你真的必须用所有内连接进行筛选吗?考虑一下(这不是一个完整的查询,而是建议的不同筛选方法:)

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, 
    sall.id AS screening_id, sall.date AS screening_date, sall.maileddate AS     screening_maileddate
FROM users 
LEFT JOIN clients
ON(
   users.client_id = clients.id
   AND users.client_id = '1879'
)
LEFT JOIN hra
ON(
   users.id = hra.user_id
   AND hra.date BETWEEN '2011-07-01' AND '2011-11-15'
   AND hra.maileddate IS NOT NULL 
)
LEFT JOIN screening sall
ON(
   sall.user_id = users.id 
)
WHERE users.id NOT IN
(
  SELECT user_id FROM screening1
  WHERE user_id = users.id AND
        colesterol IS NULL
        date BETWEEN '2011-05-15' AND '2011-11-15'
) 
OR users.id NOT IN
(
  SELECT user_id FROM screening2
  WHERE user_id = user.id AND
        ldl IS NULL
        date BETWEEN '2011-05-15' AND '2011-11-15'
) 
...