Вывести значение одного столбца на основе других значений столбца в SQL Server - PullRequest
0 голосов
/ 19 апреля 2019

Если скорость дня составляет> 0, ее состояние равно true.

В случае отсутствия данных за конкретный день, выведите значение последнего кода состояния (еще один столбец
в таблице) иесли значение равно нулю, пометьте статус запуска как true.Для кодов, отличных от статуса нуля, отметьте как ложное.

См. Таблицу ниже

Day       Run speed Statuscode  Status  
---------------------------------------
1-Jan-14    55         0        TRUE  
2-Jan-14    60         0        TRUE  
3-Jan-14    58         0        TRUE  
4-Jan-14    61         0        TRUE  
5-Jan-14    57         0        TRUE  
6-Jan-14    56         0        TRUE  
7-Jan-14    60         0        TRUE  
8-Jan-14                        TRUE  
9-Jan-14                        TRUE  
10-Jan-14   55         0        TRUE  
11-Jan-14   56         0        TRUE  
12-Jan-14   60         0        TRUE  
13-Jan-14    0        20        FALSE  

(пример 8-jan-14/9-jan-14 не имеет значения, но поскольку 7-й былзаписано в последний раз, и это правда, поэтому статус этих двух дат также верен)

Ответы [ 3 ]

0 голосов
/ 19 апреля 2019

Что вам действительно нужно для этого, так это LAG(IGNORE NULLS), но SQL Server не поддерживает это.

Вы можете использовать другой прием, который заключается в получении максимальной даты, когда статус равен 0, и максимальной даты.где статус не 0 и сравните их.Итак:

select t.*,
       (case when statuscode = 0 then 'TRUE'
             when statuscode <> 0 then 'FALSE'
             when (max(case when statuscode = 0 then day end) over (order by day) >
                   coalesce(max(case when statuscode <> 0 day date end) over (order by day), '2000-01-01')
                  )
             then 'TRUE'
             else 'FALSE'
        end) as status
from t;

Здесь - это дБ <> скрипка.

Вы можете упростить это до последних условий:

select t.*,
       (case when (max(case when statuscode = 0 then day end) over (order by day) >
                   coalesce(max(case when statuscode <> 0 then day end) over (order by day), '2000-01-01')
                  )
             then 'TRUE'
             else 'FALSE'
        end) as status
from t;

Первая версия лучше соответствует логике, которую вы описываете.

Я не могу сказать из вопроса, хотите ли вы основывать логику на runningspeed или statuscode.Логика была бы очень похожа на runningspeed.

0 голосов
/ 19 апреля 2019

Используйте OUTER APPLY как более гибкую задержку

Тест в реальном времени: http://sqlfiddle.com/#!18/4c73f/18

select 
    o.*,
    Status = 
        convert(bit,
            case 
                when o.RunningSpeed > 0 
                or   o.RunningSpeed is null and prev.StatusCode = 0 then 
                    1
                else 
                    0
            end)    
from tbl o
outer apply
(
    select top 1 StatusCode
    from tbl i
    where i.Day < o.Day and i.StatusCode is not null
    order by i.Day desc
) prev

Вывод:

|                  Day | RunningSpeed | Statuscode | Status |
|----------------------|--------------|------------|--------|
| 2014-01-01T00:00:00Z |           55 |          0 |   true |
| 2014-01-02T00:00:00Z |           60 |          0 |   true |
| 2014-01-03T00:00:00Z |           58 |          0 |   true |
| 2014-01-04T00:00:00Z |           61 |          0 |   true |
| 2014-01-05T00:00:00Z |           57 |          0 |   true |
| 2014-01-06T00:00:00Z |           56 |          0 |   true |
| 2014-01-07T00:00:00Z |           60 |          0 |   true |
| 2014-01-08T00:00:00Z |       (null) |     (null) |   true |
| 2014-01-09T00:00:00Z |       (null) |     (null) |   true |
| 2014-01-10T00:00:00Z |           55 |          0 |   true |
| 2014-01-11T00:00:00Z |           56 |          0 |   true |
| 2014-01-12T00:00:00Z |           60 |          0 |   true |
| 2014-01-13T00:00:00Z |            0 |         20 |  false |
0 голосов
/ 19 апреля 2019

A CASE заявление решит это для вас. И OUTER APPLY решит второе требование.

APPLY, CROSS APPLY и OUTER APPLY как наиболее понятные и недостаточно используемые итераторы, на мой взгляд. Но как только вы поймете их силу и поймете варианты использования, они станут смертельным оружием в вашем наборе инструментов. Они особенно полезны в TOP(n) [by some logic] ситуациях, когда встроенные функции не соответствуют вашим требованиям.

Обратите внимание на использование BIT для представления логического значения TRUE/FALSE

SELECT Day
     , RunningSpeed
     , PreviousRunningSpeed
     , CASE 
        WHEN RunningSpeed IS NULL AND PreviousRunningSpeed > 0 THEN 1
        WHEN RunningSpeed > 0 THEN 1
        ELSE 0
       END AS Status 
  FROM (SELECT Day
             , RunningSpeed  
             , d.RunningSpeed AS PreviousRunningSpeed            
          FROM tbl AS t1
               OUTER APPLY (SELECT TOP(1) 
                                   RunningSpeed
                              FROM tbl AS t2
                             WHERE RunningSpeed IS NOT NULL
                                   AND t2.Day < t1.Day
                             ORDER BY Day ASC)) AS d
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...