Модераторы: skyboy
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проверка включения в заданный период времени, select со сложной группировкой по дате 
V
    Опции темы
Garmahis
Дата 8.10.2015, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 23.12.2004

Репутация: 1
Всего: 4



Добрый день!
Помогите составить сложный запрос.
Есть таблица в которой храниться изменение состояния для объекта.
Вот пример таблицы:
Код

DECLARE @T TABLE (ID int, DT datetime, IS_ACTUAL int)
INSERT INTO @T (ID, DT, IS_ACTUAL)
VALUES
(1,'20150925',1),
(1,'20150926',0), --Нет
(2,'20150925',1),
(2,'20150926',0),
(2,'20150927',1), --Да
(3,'20150925',1), --Да
(4,'20150925',0), --Нет
(5,'20150925',1),
(5,'20150926',0),
(5,'20151005 12:00:00',1),
(5,'20151005 13:00:00',0), --Нет 
(6,'20150925',1),
(6,'20150926',0),
(6,'20151005',1), --Да
(6,'20151006',0),
(7,'20150925',0), 
(7,'20150926',1),
(7,'20151005',0),  --Да
(8,'20150926',0),
(8,'20151010',1)  --Нет

ID - ID объекта. DT - дата изменения состояния. IS_ACTUAL соотвествено само состояние. К обьекту состояние применяется в полночь. Поэтому если состояние меняется в течении дня то актуально только то которое последнее. 
Задача. Надо вывести все ID c их состояниями на некий период дат. Если в этот период объект был хоть раз включен тогда 1 если нет то 0.
Код

DECLARE @DT_FROM Datetime, @DT_TO DATETIME
SET @DT_FROM = '20151001'
SET @DT_TO = '20151010'

Помогите пожалуйста! 
PM   Вверх
Akina
Дата 8.10.2015, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20570
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 45
Всего: 453



Указывайте СУБД. На разных серверах порой нужно использовать принципиально разные методы.

Добавлено через 1 минуту и 22 секунды
Кстати, а какой смысл хранить ВСЕ изменения за день, если все, кроме последнего, игнорируются?


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Garmahis
Дата 8.10.2015, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 23.12.2004

Репутация: 1
Всего: 4



СУБД MS SQL 2008R2
К сожалению это сохранилось исторически. Там еще логируется кто вносил изменения.
PM   Вверх
Akina
Дата 8.10.2015, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20570
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 45
Всего: 453



Код

SELECT 
  ID
, MAX( CASE 
       WHEN DT BETWEEN @DT_FROM AND @DT_TO
       THEN IS_ACTUAL 
       ELSE 0 
       END
     ) WAS_ACTUAL
FROM @T
GROUP BY ID



--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Garmahis
Дата 8.10.2015, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 23.12.2004

Репутация: 1
Всего: 4



Не получается не правильно. так предполагается что изменения были обязательно в этот период. А ведь он может быть включен до начала. В приведенном примере такой запрос например для ID IN (2,3,7) пишет 0 а на самом деле 1. Так же в ID = 5 он должен писать 0 так как 5 числа он был включен но через час отключен значит при обновлении состояния в полночь объект не был включен.
PM   Вверх
Akina
Дата 8.10.2015, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20570
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 45
Всего: 453



Garmahis, надо быть аккуратнее в своих формулировках. Например, с такими уточнениями какая нафиг разница, какое брать @DT_FROM???

Посмотри вот на такое, например:

Код

SELECT id, MAX(is_actual) "WAS_ACTUAL"
FROM ( SELECT id, is_actual, ROW_NUMBER() OVER (PARTITION BY id, DAY(dt), MONTH(dt), YEAR(dt) ORDER BY dt DESC) "RN"
       FROM @t
       WHERE dt < @DT_TO
     ) sq
WHERE RN=1
GROUP BY id



--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
jsharp36
Дата 10.10.2015, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 8.10.2011

Репутация: нет
Всего: 1



Код

SELECT ID, CASE WHEN SUM(IS_ACTUAL) > 0 THEN 1 ELSE 0 END AS WAS_ACTUAL FROM
(
    SELECT RANK() OVER (PARTITION BY ID, CAST(DT as DATE) ORDER BY DT DESC) AS [RANK],
           ID, DT, IS_ACTUAL
    FROM @T
) T
WHERE [RANK] = 1 AND DT BETWEEN @DT_FROM AND @DT_TO
GROUP BY ID


Этот ответ добавлен с нового Винграда - http://vingrad.com
PM MAIL   Вверх
jsharp36
Дата 10.10.2015, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 8.10.2011

Репутация: нет
Всего: 1



Или заменить CASE WHEN SUM(IS_ACTUAL) > 0 THEN 1 ELSE 0 END на MAX(IS_ACTUAL) - как выше написали. Меньше символов

Этот ответ добавлен с нового Винграда - http://vingrad.com
PM MAIL   Вверх
Garmahis
Дата 23.10.2015, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 23.12.2004

Репутация: 1
Всего: 4



Спасибо большое!!!
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Составление SQL-запросов | Следующая тема »


 




[ Время генерации скрипта: 0.1259 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.