2015-07-16 1 views
0

У меня есть таблица с большим количеством записей, но, к примеру ..Выберите строку, где все записи с одинаковыми строками встречаются условиями

ID | USER ID | DATE 
1 | 1  | 2014-05-26 
2 | 1  | 2015-05-08 
3 | 2  | 2014-05-20 

Я пытаюсь выбрать USER_ID для записей, дата которых более 6 месяцев прошли, но не включайте их, если есть еще одна запись с тем же USER_ID, которая не соответствует этим критериям. Так, например, я хотел бы вернуть только запись с идентификатором пользователя 2.

Мой вопрос я могу сделать

SELECT USER_ID FROM TABLE WHERE DATEDIFF(month, DATE, GETDATE()) > 6 

но что будет возвращать запись с USER_ID 1. Я уверен, что это очень просто, но я не смог добиться этого.

ответ

1

Просто возьмите ваше заявление и принять другие прочь:

WITH UsersWithYoungerDates AS 
    (
     SELECT USER_ID 
     FROM TABLE 
     WHERE DATEDIFF(month, DATE, GETDATE()) <= 6 
    ) 
    SELECT USER_ID 
    FROM TABLE 
    WHERE DATEDIFF(month, DATE, GETDATE()) > 6 
    AND USER_ID NOT IN(SELECT USER_ID FROM UsersWithYoungerDates) 
+0

Использование предложения WITH возвращено «Неверный синтаксис рядом с ключевым словом« с ». Если этот оператор является общим табличным выражением, предложением xmlnamespaces или предложением контекста отслеживания изменений, предыдущий оператор должен быть прерван точкой с запятой ». Не знаете, в чем проблема. – wizloc

+1

Есть ли предыдущий оператор? В любом случае, вы должны получить в привычку добавлять точки с запятой в _all_ заявления, поскольку MS отметила, что это _might_ станет обязательным в будущем. (Возможно, несколько маловероятно, но зачем рисковать?) –

+0

@ user3299574: Просто начните с символа «;» перед WITH. И, пожалуйста, отметьте это как принято, если это решит вашу prblem, thx – Shnugo

1

Нравится?

SELECT USER_ID 
FROM TABLE 
WHERE DATEDIFF(month, DATE, GETDATE()) > 6 AND USER_ID NOT IN 
    (
     SELECT USER_ID 
     FROM TABLE 
     WHERE DATEDIFF(month, DATE, GETDATE()) <= 6 
    ) 
1
SELECT USER_ID 
FROM [TABLE] 
WHERE DATEDIFF(month, DATE, GETDATE()) > 6 
and USER_ID not in (
    select USER_ID 
    from [TABLE] 
    where 6 <= datediff(month, date, getdate()) 
); 

Примечание это фильтр, чтобы 7 месяцев или больше, а не "более чем на 6 месяцев". DATEDIFF округляется. Возможно, вы захотите пересмотреть этот аспект своего первоначального плана.

Также вы, вероятно, знаете это, но TABLE является зарезервированным словом, поэтому, если бы это был не просто (ошибочный: P) -заполнитель, ему нужны разделители идентификаторов.

2

Вы можете использовать следующий запрос:

SELECT USER_ID 
FROM mytable 
GROUP BY USER_ID 
HAVING COUNT(CASE WHEN DATEDIFF(month, [DATE], GETDATE()) <= 6 THEN 1 END) = 0 

выше исключит любые USER_ID S, имеющий по меньшей мере, один ряд которого DATE является 6 или менее 6 месяцев.

Demo here

Если вы хотите, чтобы выбрать все поля, то вы можете использовать оконную версию условного COUNT как:

SELECT * 
FROM (
    SELECT *, 
     COUNT(CASE WHEN DATEDIFF(month, [DATE], GETDATE()) <= 6 THEN 1 END) 
     OVER (PARTITION BY USER_ID) AS cnt  
    FROM mytable) t 
WHERE cnt = 0 

Demo here

или, в качестве альтернативы, используйте NOT EXISTS:

SELECT * 
FROM mytable AS t1 
WHERE NOT EXISTS (SELECT 1 
        FROM mytable AS t2 
        WHERE t1.USER_ID = t2.USER_ID 
         AND DATEDIFF(month, t2.[DATE], GETDATE()) <= 6) 

Demo here

Смежные вопросы