Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Вывод значений за предыдущий день, если есть NULL  [new]
_Дмитрий08_
Member

Откуда:
Сообщений: 13
ДОбрый день уважаемые форумчане. Помогите решить, пожалуста, следующую проблему:
Есть вот такой запрос:
Declare @Дата_Начала datetime2; 
Declare @Дата_Конца datetime2;
SET @Дата_Начала = '20130528';
SET @Дата_Конца = '20130531';
; WITH all AS (SELECT     T1.[Id], T1.[TestName], T1.[SourceName], H1.[DateTime], H1.[TId], H1.[Value], Odesc.Description
FROM          [Test].[History] AS H1 INNER JOIN
[Test].[Test] AS T1 ON H1.TID = T1.ID INNER JOIN
[Object].[ObjectParameter] AS ObPr ON T1.SourceName = ObPr.TName INNER JOIN
[Object].[Object] AS Odesc ON ObPr.[ObjectGuid] = Odesc.[Guid]),
test1 AS
    (SELECT     *
      FROM          all
      WHERE     SourceName like  '%.Epotre'),
test2 AS
    (SELECT     *
      FROM          all
      WHERE      SourceName like '%.Debji'), 
day_test1 AS
    (SELECT     test1.SourceName AS EnST, cast(test1.DateTime) AS date) AS ДатаВремя, ROUND(avg(test1.Value), 2) AS EnValue, 
                test1.TId AS EnTid, test1.Description as SCVdescrEN
      FROM     test1
      WHERE     test1.DateTime BETWEEN dateadd(hour, - 6, @Дата_Начала) AND dateadd(hour, 18, @Дата_Конца)
      GROUP BY test1.SourceName, cast(test.DateTime) AS date), Test1.TId, Test1.Description), 
day_test2 AS
    (SELECT   test2.SourceName AS FlST5, cast(test2.DateTime) AS date) AS ДатаВремя5, ROUND(avg(test2.Value), 2) AS FlValue5, 
             test2.TId AS FlTid5, test2.Description as SCVdescrFL
      FROM   test2
      WHERE     test2.DateTime BETWEEN dateadd(hour, - 6, @Дата_Начала) AND dateadd(hour, 18, @Дата_Конца)
      GROUP BY test2.SourceNAme, cast(test2.DateTime) AS date), test2.TId, test2.Description )

    SELECT     EnST, ДатаВремя, EnValue AS Знач1, EnTid, SCVdescrEN, FlST5,ДатаВремя5, FlValue5 AS Знач2,
     FlTid5, SCVdescrFL 
     FROM         day_test1 LEFT JOIN
                            day_test2 ON ДатаВремя = ДатаВремя5 and SCVdescrEN = SCVdescrFL
 
     GROUP BY EnST, ДатаВремя, EnTid,FlST5, ДатаВремя5, FlTid5, EnValue, FlValue5, SCVdescrEN, SCVdescrFL

Результат запроса:
EnST|ДатаВремя|Знач1|EnTid|SCVdescrEN|FlST5|ДатаВремя5|Знач2|FlTid5|SCVdescrFL
664.Epotre|30.05.2013|978,1|472260|111|NULL|NULL|NULL|NULL| NULL
664.Epotre|28.05.2013|898,5|472260|111|664.Debji|28.05.2013|26,1|472294|111
664.Epotre|29.05.2013|927,2|472260|111|664.Debji|29.05.2013|33,3|472294|111
664.Epotre|31.05.2013|969,2|472260|111|664.Debji|31.05.2013|29,25|472294|111
663.Epotre|30.05.2013|622,91|472254|222|NULL|NULL|NULL|NULL|NULL
663Epotre|28.05.2013|616,69|472254|222|663.Debji|28.05.2013|28,3|472258|222
663.Epotre|29.05.2013|618,85|472254|222|663.Debji|29.05.2013|30,7|472258|222
663.Epotre|31.05.2013|626,18|472254|222|663.Debji|31.05.2013|30,1|472258|222

Необходимо чтобы вместо NULL в столбце Знач2 подставлялось значение за предыдущий день.
Например, если смотреть первую строчку, то вместо NULL в столбце Знач2 необходимо поставить 33,3, в 5 строке должно подставиться 30,7 и.т.д.
Помогите, пожалуста, решить данную задачу, уже как только не пробовал

Сообщение было отредактировано: 5 июн 13, 08:47
5 июн 13, 08:47    [14392287]     Ответить | Цитировать Сообщить модератору
 Re: Вывод значений за предыдущий день, если есть NULL  [new]
Сергей Викт.
Member

Откуда: Москва
Сообщений: 888
_Дмитрий08_,

Доброе утро, Дмитрий.

Попробуйте, может быть, так:

 SELECT     EnST, ДатаВремя, EnValue AS Знач1, EnTid, SCVdescrEN, FlST5,ДатаВремя5, 
ISNULL(FlValue5, (SELECT d2.FlValue5 FROM daytest2 d2 WHERE d2.ДатаВремя5=DATEADD(DAY,-1,day_test1.ДатаВремя)))
   AS Знач2, FlTid5, SCVdescrFL 
     FROM         day_test1 LEFT JOIN
                            day_test2 ON ДатаВремя = ДатаВремя5 and SCVdescrEN = SCVdescrFL
5 июн 13, 09:20    [14392395]     Ответить | Цитировать Сообщить модератору
 Re: Вывод значений за предыдущий день, если есть NULL  [new]
_Дмитрий08_
Member

Откуда:
Сообщений: 13
Сергей Викт.
_Дмитрий08_,

Доброе утро, Дмитрий.

Попробуйте, может быть, так:

 SELECT     EnST, ДатаВремя, EnValue AS Знач1, EnTid, SCVdescrEN, FlST5,ДатаВремя5, 
ISNULL(FlValue5, (SELECT d2.FlValue5 FROM daytest2 d2 WHERE d2.ДатаВремя5=DATEADD(DAY,-1,day_test1.ДатаВремя)))
   AS Знач2, FlTid5, SCVdescrFL 
     FROM         day_test1 LEFT JOIN
                            day_test2 ON ДатаВремя = ДатаВремя5 and SCVdescrEN = SCVdescrFL


Сергей, в этом случае SQL сразу ругается:
"Вложенный запрос вернул больше одного значения. Это запрещено, когда вложенный запрос следует после =, !=, <, <=, >, >= или используется в качестве выражения"
Если делать вот так:
ISNULL(FlValue5, (SELECT  top (1) d2.FlValue5 FROM daytest2 d2 WHERE d2.ДатаВремя5=DATEADD(DAY,-1,day_test1.ДатаВремя)))

Тогда в результате вместо NULL, он подставляет одно и тоже значение, что неправильно. Вот голову и ломаю в связи с этим.
5 июн 13, 11:18    [14393116]     Ответить | Цитировать Сообщить модератору
 Re: Вывод значений за предыдущий день, если есть NULL  [new]
Сергей Викт.
Member

Откуда: Москва
Сообщений: 888
_Дмитрий08_
Сергей Викт.
_Дмитрий08_,

Доброе утро, Дмитрий.

Попробуйте, может быть, так:

 SELECT     EnST, ДатаВремя, EnValue AS Знач1, EnTid, SCVdescrEN, FlST5,ДатаВремя5, 
ISNULL(FlValue5, (SELECT d2.FlValue5 FROM daytest2 d2 WHERE d2.ДатаВремя5=DATEADD(DAY,-1,day_test1.ДатаВремя)))
   AS Знач2, FlTid5, SCVdescrFL 
     FROM         day_test1 LEFT JOIN
                            day_test2 ON ДатаВремя = ДатаВремя5 and SCVdescrEN = SCVdescrFL


Сергей, в этом случае SQL сразу ругается:
"Вложенный запрос вернул больше одного значения. Это запрещено, когда вложенный запрос следует после =, !=, <, <=, >, >= или используется в качестве выражения"
Если делать вот так:
ISNULL(FlValue5, (SELECT  top (1) d2.FlValue5 FROM daytest2 d2 WHERE d2.ДатаВремя5=DATEADD(DAY,-1,day_test1.ДатаВремя)))

Тогда в результате вместо NULL, он подставляет одно и тоже значение, что неправильно. Вот голову и ломаю в связи с этим.

ISNULL(FlValue5, (SELECT  top (1) d2.FlValue5 FROM daytest2 d2 WHERE d2.ДатаВремя5=DATEADD(DAY,-1,day_test1.ДатаВремя))) 


Добавьте ещё: SCVdescrEN = SCVdescrFL

ISNULL(FlValue5, (SELECT  top (1) d2.FlValue5 FROM daytest2 d2 WHERE d2.ДатаВремя5=DATEADD(DAY,-1,day_test1.ДатаВремя AND SCVdescrEN = d2.SCVdescrFL))) 
5 июн 13, 11:22    [14393162]     Ответить | Цитировать Сообщить модератору
 Re: Вывод значений за предыдущий день, если есть NULL  [new]
_Дмитрий08_
Member

Откуда:
Сообщений: 13
Сергей Викт.
_Дмитрий08_
пропущено...


Сергей, в этом случае SQL сразу ругается:
"Вложенный запрос вернул больше одного значения. Это запрещено, когда вложенный запрос следует после =, !=, <, <=, >, >= или используется в качестве выражения"
Если делать вот так:
ISNULL(FlValue5, (SELECT  top (1) d2.FlValue5 FROM daytest2 d2 WHERE d2.ДатаВремя5=DATEADD(DAY,-1,day_test1.ДатаВремя)))

Тогда в результате вместо NULL, он подставляет одно и тоже значение, что неправильно. Вот голову и ломаю в связи с этим.

ISNULL(FlValue5, (SELECT  top (1) d2.FlValue5 FROM daytest2 d2 WHERE d2.ДатаВремя5=DATEADD(DAY,-1,day_test1.ДатаВремя))) 


Добавьте ещё: SCVdescrEN = SCVdescrFL

ISNULL(FlValue5, (SELECT  top (1) d2.FlValue5 FROM daytest2 d2 WHERE d2.ДатаВремя5=DATEADD(DAY,-1,day_test1.ДатаВремя AND SCVdescrEN = d2.SCVdescrFL))) 

Спасибо Сергей в действительности не хватало этого условия.
Только теперь еще один нюанс появился:
Например, за 28 число есть значение, а за 29, 30, 31 - NULL.
В результате получается, что за 29 проставляется значение, а за 30 и 31 также остается NULL. Хотя должен был проставить значение за 28 число.
5 июн 13, 12:20    [14393650]     Ответить | Цитировать Сообщить модератору
 Re: Вывод значений за предыдущий день, если есть NULL  [new]
Сергей Викт.
Member

Откуда: Москва
Сообщений: 888
_Дмитрий08_
Сергей Викт.
пропущено...

ISNULL(FlValue5, (SELECT  top (1) d2.FlValue5 FROM daytest2 d2 WHERE d2.ДатаВремя5=DATEADD(DAY,-1,day_test1.ДатаВремя))) 


Добавьте ещё: SCVdescrEN = SCVdescrFL

ISNULL(FlValue5, (SELECT  top (1) d2.FlValue5 FROM daytest2 d2 WHERE d2.ДатаВремя5=DATEADD(DAY,-1,day_test1.ДатаВремя AND SCVdescrEN = d2.SCVdescrFL))) 

Спасибо Сергей в действительности не хватало этого условия.
Только теперь еще один нюанс появился:
Например, за 28 число есть значение, а за 29, 30, 31 - NULL.
В результате получается, что за 29 проставляется значение, а за 30 и 31 также остается NULL. Хотя должен был проставить значение за 28 число.

Вначале вы написали условие, что за предыдущее число, а не за последнее существующее.
Сейчас подумаю, как лучше сделать
5 июн 13, 12:24    [14393694]     Ответить | Цитировать Сообщить модератору
 Re: Вывод значений за предыдущий день, если есть NULL  [new]
Добрый Э - Эх
Guest
_Дмитрий08_,

STFF. Только чур - читать до конца... ;)
5 июн 13, 12:28    [14393717]     Ответить | Цитировать Сообщить модератору
 Re: Вывод значений за предыдущий день, если есть NULL  [new]
Добрый Э - Эх
Guest
Сергей Викт.
Сейчас подумаю, как лучше сделать
Если ничего не придумаешь, то можешь подсмотреть решение тут ;)
5 июн 13, 12:29    [14393722]     Ответить | Цитировать Сообщить модератору
 Re: Вывод значений за предыдущий день, если есть NULL  [new]
Сергей Викт.
Member

Откуда: Москва
Сообщений: 888
Добрый Э - Эх
Сергей Викт.
Сейчас подумаю, как лучше сделать
Если ничего не придумаешь, то можешь подсмотреть решение тут ;)

Да я рою старые скрипты и процедуры. Делали похожее на старой работе) Ту тему читал как раз, когда делал:)
5 июн 13, 12:32    [14393737]     Ответить | Цитировать Сообщить модератору
 Re: Вывод значений за предыдущий день, если есть NULL  [new]
_Дмитрий08_
Member

Откуда:
Сообщений: 13
Сергей Викт.
_Дмитрий08_
пропущено...

Спасибо Сергей в действительности не хватало этого условия.
Только теперь еще один нюанс появился:
Например, за 28 число есть значение, а за 29, 30, 31 - NULL.
В результате получается, что за 29 проставляется значение, а за 30 и 31 также остается NULL. Хотя должен был проставить значение за 28 число.

Вначале вы написали условие, что за предыдущее число, а не за последнее существующее.
Сейчас подумаю, как лучше сделать

Сергей спасибо Вам за помощь с решением данной задачи.
Я решил ее вот так:
ISNULL(FlValue5, (SELECT d2.FlValue5 FROM daytest2 d2 WHERE d2.ДатаВремя5<day_test1.ДатаВремя and SCVdescrEN = d2.SCVdescrFL order by d2.ДатаВремя5 desc )) AS Знач2 
5 июн 13, 13:35    [14394335]     Ответить | Цитировать Сообщить модератору
 Re: Вывод значений за предыдущий день, если есть NULL  [new]
_Дмитрий08_
Member

Откуда:
Сообщений: 13
Поправочка
ISNULL(FlValue5, (SELECT top (1) d2.FlValue5 FROM daytest2 d2 WHERE d2.ДатаВремя5<day_test1.ДатаВремя and SCVdescrEN = d2.SCVdescrFL order by d2.ДатаВремя5 desc )) AS Знач2 
5 июн 13, 13:37    [14394367]     Ответить | Цитировать Сообщить модератору
 Re: Вывод значений за предыдущий день, если есть NULL  [new]
12345906
Guest
Немного не понятно, а почему вы не хотите выбирать MAX (самый последний) из дней? последний как раз будет нужным
5 июн 13, 15:03    [14395083]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить