2012-05-24 2 views
1

У меня есть образец данных, как этотПечать текущего значения и предыдущего значения между диапазон дат

ID  DATE   TIME  STATUS 
--------------------------------------------- 
A  01-01-2000  0900  ACTIVE 
A  05-02-2000  1000  INACTIVE 
A  01-07-2000  1300  ACTIVE 
B  01-05-2005  1000  ACTIVE 
B  01-08-2007  1050  ACTIVE 
C  01-01-2010  0900  ACTIVE 
C  01-07-2010  1900  INACTIVE 

Из указанного выше набора данных, если мы только сосредоточиться на ID='A' мы отмечаем, что A был Initally активным, а затем стал неактивен на 05-02-2000, а затем он неактивен до 01-07-2000.

Это значит, что A был не активным с 05-Feb-2000 по 01-July-2000.

Мои вопросы:

  1. если я выполнить запрос с (ID=A, Date=01-04-2000) он должен дать мне

    A  05-02-2000  1000  INACTIVE 
    

    , потому что с этой даты не доступны в этом наборе данных, он должен искать для предыдущий и распечатать, что

  2. Кроме того, если мое состояние (ID=A, Date=01-07-2000), оно должно не только печатать значение, которое присутствует в t он стол, но и напечатать предыдущее значение

    A  05-02-2000  1000  INACTIVE 
    A  01-07-2000  1300  ACTIVE 
    

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

Благодарим всех.

Любое взятие этого?

Afaq

ответ

1

Нечто подобное должно работать:

SELECT ID, Date, Time, Status 
from (select ID, Date, Time, Status, row_number() over (order by Date) Ranking 
     from MyTable 
     where ID = @SearchId 
     and Date <= @SearchDate) xx 
where Ranking < 3 
order by Date, Time 

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


Учитывая пересмотренные критерии, это становится немного сложнее, так как включение или исключение строки зависит от значения возвращается в другой строке. Здесь «вторая» строка, если есть две или более строк, включена только в том случае, если «первая» строка равна конкретному значению. Стандартный способ сделать это - запросить данные для получения максимального значения, а затем запросить его снова, ссылаясь на результат первого набора.

Однако вы можете сделать много шуточных вещей с row_number. Работа над этим:

SELECT ID, Date, Time, Status 
from (select 
      ID, Date, Time, Status 
     ,row_number() over (partition by case when Date = @SearchDate then 0 else 1 end 
          order by  case when Date = @SearchDate then 0 else 1 end 
             ,Date) Ranking 
     from MyTable 
     where ID = @SearchId 
     and Date <= @SearchDate) xx 
where Ranking = 1 
order by Date, Time 

Вам необходимо решить проблему с датой/временем, поскольку это работает только с датами.

+0

Спасибо за быстрый ответ Филиппа, но здесь мне нужно быть более конкретными о выходе я получаю. Нам нужно изменить это решение таким образом, чтобы, если точная дата соответствует ему, должна печатать тот же результат, а также предыдущий предыдущий; но если это не так, он должен печатать только предыдущий. Не могли бы вы заглянуть в это условие. – Afaq

+0

Еще раз спасибо Филип. Да, мои столбцы даты - это тип данных даты, и они называются разными. Я упомянул их здесь только для справки. Кстати, я не понял новый запрос, который вы здесь дали. Какова дата импорта данных здесь? – Afaq

+0

Я очень ценю то время, которое вы мне даете. с нетерпением жду решения – Afaq

0

В основном вам нужно вытащить строку, если для указанной даты, это:

1) последнюю запись, или

2) последнего неактивной записи.

И оба условия могут совпадать с одним и тем же рядом, а также с двумя разными строками.

Вот как эта логика может быть реализована в SQL Server 2005+:

WITH ranked AS (
    SELECT 
    ID, 
    Date, 
    Time, 
    Status, 
    RankOverall = ROW_NUMBER() OVER (     ORDER BY Date DESC), 
    RankByStatus = ROW_NUMBER() OVER (PARTITION BY Status ORDER BY Date DESC) 
    FROM Activity 
    WHERE ID = @ID 
    AND Date <= @Date 
) 
SELECT 
    ID, 
    Date, 
    Time, 
    Status, 
FROM ranked 
WHERE RankOverall = 1 
    OR Status = 'INACTIVE' AND RankByStatus = 1 
+0

Спасибо Andriy за ваш ответ, но я не понял, почему вы разделились на Status. Это не важно для меня. Я объяснил статус в контексте на сегодняшний день и продолжение деятельности. Я попробовал ваш ответ, и я как-то близко. – Afaq

+0

В вашем случае я проверил, что если я не установлю никаких условий над ID ... Я не получаю вывод ... предполагаю, что мое условие ввода - это только дата или диапазон дат ... – Afaq

+0

Примите пример I введите такой вопрос: Покажите мне все ID и их записи между диапазоном дат 20-02-2010 по 22-02-2010. Он должен показать мне результат ID = A, ACTIVE, ID = B как активный и ID = C как активный. Здесь ID = C не может быть неактивным, потому что он неактивен в июле. Рассмотрите мой столбец с датой как тип данных даты – Afaq

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