Как объединить со многими условиями на нескольких столах - PullRequest
0 голосов
/ 08 сентября 2011

Я работаю над написанием запроса, который может проверять несколько строк одного и того же пользователя.Если комбинация записей одного и того же пользователя не дает необходимой мне информации (помните, что это комбинация всех записей, которые есть у пользователя, а не одной), то пользователь считается пропущенным.

Например,: Есть две таблицы.

Одна - это «пользователь», в которой хранится личная информация пользователя:

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 и триглицеридов, пока один из них отсутствует, пользователь должен быть выбран.Но для глюкозы и 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 голосов
/ 08 сентября 2011

Похоже, вы хотите ИЛИ вместо И Кроме того, если вы хотите, чтобы они были выбраны, когда чего-то не хватает, выберите «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))
0 голосов
/ 08 сентября 2011

Проверяя NOT NULL в предложении WHERE, вы побеждаете цель ЛЕВОГО СОЕДИНЕНИЯ и, по сути, превращаете его в ВНУТРЕННЕЕ СОЕДИНЕНИЕ ...

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.

0 голосов
/ 08 сентября 2011

Просто переместите условия, которые сверяются с лабораториями, с 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)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...