2009-02-18 3 views
0

С помощью SQL Server 2005 у меня есть таблица, в которой регистрируются определенные события, и мне нужно создать запрос, который возвращает только очень конкретные результаты. Там пример ниже:SQL-запрос фильтрации

 
Log: 
Log_ID | FB_ID | Date | Log_Name | Log_Type 

    7 | 4 | 2007/11/8 | Nina | Critical 
    6 | 4 | 2007/11/6 | John | Critical 
    5 | 4 | 2007/11/6 | Mike | Critical 
    4 | 4 | 2007/11/6 | Mike | Critical 
    3 | 3 | 2007/11/3 | Ben | Critical 
    2 | 3 | 2007/11/1 | Ben | Critical 

Запрос должен выполнить следующие действия: возвращать только одну строку на каждый FB_ID, но это должно быть один, где log_name изменилось в первый раз, или если имя не меняется, затем первый датированный ряд.

В условиях непрофессионала мне нужно это, чтобы просмотреть БД, чтобы проверить каждый экземпляр, в котором ответственность за дело (FB_ID) была перенесена на другого человека, а в случае, если это никогда не было, просто введите имя оригинального регистратора ,

В приведенном выше примере, я должен получить строки (Log_ID) 2 и 6.

даже возможно ли это? Прямо сейчас идет дискуссия о том, была ли БД просто ошибочной. :)

Я предполагаю, что мне нужно как-то сохранить первое результирующее имя Log_Name в переменной, а затем сравнить его с условием IF и т. Д. Я понятия не имею, как это сделать с SQL.

Редактировать: Обновлена ​​дата. И уточнить на это, правильный результат будет выглядеть следующим образом:

 
Log_ID | FB_ID | Date | Log_Name | Log_Type 

    6 | 4 | 2007/11/6 | John | Critical 
    2 | 3 | 2007/11/1 | Ben | Critical 

Это не первая дата в FB_ID я после, но строка, где log_name изменяется от оригинала.

Первоначально FB_ID 4 принадлежит Майку, но запрос должен возвращать строку, в которой он переходит к Джону. Тем не менее, он НЕ должен возвращать строку, в которой он продвигается дальше к Нине, потому что первое изменение ответственности уже произошло, когда Джон получил это.

В случае с Ben с FB_ID 3 регистратор никогда не изменяется, поэтому первая строка для Бена должна быть возвращена.

+0

В вашем примере выше все даты одинаковы? Являются ли даты только или датой? –

+0

Какую платформу вы используете? – Quassnoi

+0

Ах, SQL Server 2005 –

ответ

2

Это будет эффективно использовать индекс (fb_id, cdate, id):

SELECT lo4.* 
FROM 
    (
    SELECT CASE WHEN ln.log_id IS NULL THEN lo2.log_id ELSE ln.log_id END AS log_id, 
      ROW_NUMBER() OVER (PARTITION BY lo2.fb_id ORDER BY lo2.cdate) AS rn 
    FROM (
     SELECT 
      lo.*, 
      (
      SELECT TOP 1 log_id 
      FROM t_log li 
      WHERE li.fb_id = lo.fb_id 
        AND li.cdate >= lo.cdate 
        AND li.log_id <> lo.log_id 
        AND li.log_name <> lo.log_name 
      ORDER BY 
       cdate, log_id 
      ) AS next_id 
     FROM t_log lo 
     ) lo2 
    LEFT OUTER JOIN 
     t_log ln 
    ON ln.log_id = lo2.next_id 
    ) lo3, t_log lo4 
WHERE lo3.rn = 1 
    AND lo4.log_id = lo3.log_id 
+0

+1 Лучше, чем мое решение :) –

0

Если я понял, что проблема правильно, следующий SQL должен сделать трюк:

SELECT Log_ID, FB_ID, min(Date), Log_Name, Log_Type 
FROM Log 
GROUP BY Date 

SQL, будет выбрать строку с самой ранней датой для каждого FP_ID.

+0

Не то, что я ищу, хотя бы. Я отредактировал оригинал, теперь должен ответить на ваш вопрос. :) –

3

Я думаю, что есть лучше и более производительный способ, но это, кажется, работает:

SELECT * 
    FROM log 
WHERE log_id IN 
    (SELECT MIN(log_id) 
     FROM log 
     WHERE 
     (SELECT COUNT(DISTINCT log_name) 
       FROM log log2 
       WHERE log2.fb_id = log.fb_id) = 1 
     OR log.log_name <> (SELECT log_name 
           FROM log log_3 
           WHERE log_3.log_id = 
           (SELECT MIN(log_id) 
            FROM log log4 
            WHERE log4.fb_id = log.fb_id)) 
     GROUP BY fb_id) 
+0

Ударьте меня в это - я шел по тем же линиям - upvote от меня :) –

+0

Я собираюсь сделать это прямо сейчас. Кажется, работает! –

+0

+1 Хотя SQL может использовать некоторое форматирование. Правильно выровненные ключевые слова на самом деле навредили ... ;-) – Tomalak

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

  • Нет связанных вопросов^_^