Как получить последние данные, пока критерии не будут выполнены?[SQL] - PullRequest
0 голосов
/ 19 сентября 2018

Я новичок в программировании на SQL, и мне интересно, как можно получить последнюю строку на основе критериев, которые требуют зацикливания.В VBA это простой цикл до, но в SQL я посмотрел рекурсивный CTE и попробовал подзапросы, но я не думаю, что сама база данных это поддерживает.Я использую PowerQuery из Excel для подключения к базе данных с помощью SQL

+--------+--------+--------+
| Status |  Date  | Amount |
+--------+--------+--------+
| n      | 18-Mar |    -50 |
| c      | 17-Mar |     50 |
| n      | 16-Mar |    -50 |
| c      | 15-Mar |     50 |
| n      | 14-Mar |    -50 |
| c      | 13-Mar |     50 |
| c      | 12-Mar |     50 |
+--------+--------+--------+

Результат, который я пытаюсь получить, - это дата 12 марта.По сути, логика кодирования состоит в том, чтобы получить последний статус «C» без «N» после него.

        select status,max(date) 'Max Date',amount
    from table A
    where status <> 'n' and 
-- where i dont know how to make it check to see if there's a status 'n' after max date and if so, loop back until it finds a status 'C' without having a status 'N' after --
    group by status

Большое спасибо заранее за вашу помощь!

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018

ОБНОВЛЕНИЕ

У вас может быть более 1 результата в день, и вы сказали, что хотите обеспечить следующее:

  • Текущий статус 'c'
  • Предыдущий статус (днем ранее) - 'c'
  • Нет предыдущего статуса (днем ранее) для 'n'

Так что для этого у вас естьсделать второе соединение, левое соединение, чтобы убедиться, что там нет никакой связи, что-то вроде:

SELECT a1.* FROM A
INNER JOIN A a2 ON DATEDIFF(DAY, a1.Date, a2.Date) = 1 AND a2.Status = 'c'
LEFT JOIN A a3 ON DATEDIFF(DAY, a1.Date, a3.Date) = 1 AND a3.Status = 'n'
WHERE a3.Status IS NULL

Таким образом, вы гарантируете отсутствие предыдущего статуса 'n'.

Скрипка обновлена ​​по этому сценарию: Скв. Скрипка

ОРИГИНАЛЬНАЯ ПОЧТА

Я заставил ее работать с ВНУТРЕННИМ СОЕДИНЕНИЕМ, нов моем примере поле «дата» называется «поле даты» и является целым числом.Но его можно легко изменить.

Нам нужно знать, чтобы помочь, если у вас будет одна запись в день.

В любом случае, вот пример: SQL Fiddle

Запрос будет выглядеть примерно так:

SELECT a1.* FROM A
INNER JOIN A a2 ON DATEDIFF(DAY, a1.Date, a2.Date) = 1 AND a2.Status = 'c'

Надеюсь, это поможет.

0 голосов
/ 19 сентября 2018

Приведенный ниже запрос покажет вам ВСЕ строки, не соответствующие вашим критериям, а не только последний:

select
  *
  from (
    select status, date, amount,
        lead(status) over(order by date) as next_status
      from my_table
  ) x
  where status = 'c' and next_status <> 'n'

, если вы просто хотите установить самую последнюю дату, измените ее на:

select
  max(date)
  from (
    select status, date, amount,
        lead(status) over(order by date) as next_status
      from my_table
  ) x
  where status = 'c' and next_status <> 'n'

Примечание: старайтесь избегать столбца с именем date, так как обычно это зарезервированное слово.Может быть, что-то вроде recorded_at или подобное делает вашу жизнь проще.

Редактировать: Если ваш инструмент не поддерживает подзапросы, как насчет CTE?Стоит попробовать :) Вот модифицированная версия:

with a (status, date, amount, next_status) as (
  select status, date, amount,
      lead(status) over(order by date) as next_status
    from my_table
  )
select * from a  
  where status = 'c' and next_status <> 'n'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...