Как показать столбцы в строке на firebird2.5? - PullRequest
0 голосов
/ 21 октября 2019

У меня есть одна таблица, и мне нужно сделать SQL-запрос, который преобразует строки в столбцах. Моя таблица выглядит следующим образом:

    ----------------------------------------------------------
    Id |IdR |DateFrom    |DateTo      |NameOfHappening |Amount

    293|264 |01.06.2019  |30.06.2019  |Disease 1       |2836.80
    369|600 |01.07.2019  |07.07.2019  |Disease 1       |661.92
    646|631 |01.08.2019  |11.08.2019  |Disease 1       |876.59
    647|631 |12.08.2019  |21.08.2019  |Disease 2       |796.90
    840|703 |30.09.2019  |30.09.2019  |Disease 1       |90.75
    971|718 |31.05.2019  |31.05.2019  |Disease 1       |0.00

Я написал запрос, который показывает дату, но у меня проблема с другими столбцами. Мой SQL-запрос выглядит так:

select
a.IDR,
(select max(op.DATE_FROM) from HAPP_TABLE op where op.IDR=a.IDR) as DATE_FROM_HP1,
(select max(op.DATE_TO) from HAPP_TABLE op where op.IDR=a.IDR) as DATE_TO_HP1,
(select max(op.DATE_FROM) from HAPP_TABLE op where op.IDR=a.IDR group by op.DATE_FROM order by op.DATE_FROM desc rows 2 to 2) as DATE_FROM_HP2,
(select max(op.DATE_TO) from HAPP_TABLE op where op.IDR=a.IDR group by op.DATE_FROM order by op.DATE_FROM desc rows 2 to 2) as DATE_TO_HP2,
(select max(op.DATE_FROM) from HAPP_TABLE op where op.IDR=a.IDR group by op.DATE_FROM order by op.DATE_FROM desc rows 3 to 3) as DATE_FROM_HP3,
(select max(op.DATE_TO) from HAPP_TABLE op where op.IDR=a.IDR group by op.DATE_FROM order by op.DATE_FROM desc rows 3 to 3) as DATE_TO_HP3
from HAPP_TABLE a
group by a.IDR

К этой дате столбца мне нужно подключить другие данные из столбца NameOfHappening и Amount в одной группе строк по столбцу IDR. Но данные из этого двух столбцов я не могу получить как дата запроса даты. Я должен выбрать этот столбец, чтобы он соответствовал датам. Я хочу получить что-то вроде этого:

IdR  DATE_FROM_HP1  DATE_TO_HP1   DATE_FROM_HP2  DATE_TO_HP2

264 |01.06.2019    |30.06.2019    |Disease 1|null           |null       |null
600 |01.07.2019    |07.07.2019    |Disease 1|null           |null       |null
631 |12.08.2019    |21.08.2019    |Disease 2|01.08.2019     |11.08.2019 |Disease 1
703 |30.09.2019    |30.09.2019    |Disease 1|null           |null       |null
718 |31.05.2019    |31.05.2019    |Disease 1|null           |null       |null

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

Ответы [ 2 ]

1 голос
/ 21 октября 2019

Используйте коррелированный подзапрос, чтобы получить «предыдущую» строку, а затем присоединитесь обратно:

select h.*, hprev.*  -- select whatever columns you want
from (select h.*,
             (select max(h2.date)
              from happ_table h2
              where h2.idr = h.idr and
                    h2.date_from < h.date_from
             ) as prev_date_from
      from happ_table h
     ) h left join
     happ_table hprev
     on hprev.idr = h.idr and
        hprev.date_from = h.prev_date_from;

Примечания:

  • В Firebird 3+ это намного проще с lag().
  • Я не уверен, являются ли даты уникальными. Возможно, первый столбец является правильным столбцом для указания «предыдущей» строки.
0 голосов
/ 21 октября 2019

В запросе типа select max(op.DATE_FROM) from HAPP_TABLE op where op.IDR=a.IDR есть только одна строка, поэтому добавление rows 2 to 2 или rows 3 to 3 не приведет к получению значений.

Кроме того, использование max приведет кзначения, которые не обязательно должны быть связаны друг с другом, поэтому это может привести к неправильному результату

Вы можете изменить существующий запрос, исключив использование max, применяя согласованный порядок, и выбирая определенные строки, например:

select
a.IDR,
(select op.DATE_FROM from HAPP_TABLE op where op.IDR=a.IDR order by op.DATE_FROM rows 1) as DATE_FROM_HP1,
(select op.DATE_TO from HAPP_TABLE op where op.IDR=a.IDR order by op.DATE_FROM rows 1) as DATE_TO_HP1,
(select op.DATE_FROM from HAPP_TABLE op where op.IDR=a.IDR order by op.DATE_FROM desc rows 2 to 2) as DATE_FROM_HP2,
(select op.DATE_TO from HAPP_TABLE op where op.IDR=a.IDR order by op.DATE_FROM desc rows 2 to 2) as DATE_TO_HP2,
(select op.DATE_FROM from HAPP_TABLE op where op.IDR=a.IDR order by op.DATE_FROM desc rows 3 to 3) as DATE_FROM_HP3,
(select op.DATE_TO from HAPP_TABLE op where op.IDR=a.IDR order by op.DATE_FROM desc rows 3 to 3) as DATE_TO_HP3
from HAPP_TABLE a
group by a.IDR

Однако решение, предложенное Гордоном, вероятно, лучше.

...