Выбор строки для отображения на основе набора критериев - PullRequest
1 голос
/ 25 февраля 2020

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

Допустим, у меня есть эта таблица:

ForeignKey    Product     Manufacturing     Completed
--            -------     -------------     ---------
01            Shoes       Step A            2020-02-24 00:00:00.0000000
02            Shirt       Step A            2020-02-25 00:00:00.0000000
03            Pants       Step A            2020-02-25 00:00:00.0000000
01            Shoes       Step B            2020-02-24 13:56:00.0000000
02            Shirt       Step B            NULL
03            Pants       Step B            2020-02-25 13:11:00.0000000
04            Hat         Step B            NULL
04            Hat         Step A            NULL

Мне нужно получить следующий набор результатов:

ForeignKey    Product     Manufacturing     Completed
--            -------     -------------     ---------
01            Shoes       Step B            2020-02-24 13:56:00.0000000
02            Shirt       Step B            NULL
03            Pants       Step B            2020-02-25 13:11:00.0000000
04            Hat         Step A            NULL

Я не эксперт по SQL, так что это доставляет мне много хлопот. Мне нужно соответствовать следующим критериям:

1. Вернуть строку, которая находится дальше всего в процессе производства. Это означает, что иногда завершенные даты обеих строк будут нулевыми (мне нужно будет вернуть строку шага A), иногда первая завершенная дата будет завершена, но вторая будет нулевой (в этом случае мне понадобится вернуть шаг B, потому что это сделано с первого шага), и иногда они оба будут иметь завершенные даты, и в этом случае мне нужно будет вернуть шаг B.
2. Шаг A и шаг B были выбраны для ясности этот вопрос, на самом деле имя шага A идет в алфавитном порядке после шага B, поэтому сортировка по алфавиту не будет работать.

Это заставило меня выдернуть волосы. Помощь!

Ответы [ 2 ]

0 голосов
/ 26 февраля 2020

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

with pvt as (
select * from myTable 
pivot (
  max(completed) for Manufacturing in ([Step A], [Step B])
) tmp
)
select ForeignKey, Product,
   case 
   when [Step A] is null and [Step B] is null then 'Step A' 
   else 'Step B' end as Manufacturing,
   case 
   when [Step A] is not null or [Step B] is not null then [Step B] end as Completed
from pvt
order by foreignKey;

DbFiddle Demo

0 голосов
/ 25 февраля 2020

Это то, что вы хотите?

select *
from (
    select
        t.*,
        rank() over(
            partition by foreignkey 
            order by 
                case when completed is null then 0 else 1 end, 
                completed desc, 
                manufacturing
       ) rn
    from mytable t
) t
where rn = 1
order by foreignkey

Лог c находится в предложении order by оконной функции: здесь сначала помещаются записи, чьи значения completed равны null, а затем сортируются по убыванию completed (если есть) и, наконец, по возрастанию manufacturing.

Демонстрация на DB Fiddle :

foreignkey | product | manufacturing | completed                   | rn
---------: | :------ | :------------ | :-------------------------- | -:
         1 | Shoes   | Step B        | 2020-02-24 13:56:00.0000000 |  1
         2 | Shirt   | Step B        | <em>null</em>                        |  1
         3 | Pants   | Step B        | 2020-02-25 13:11:00.0000000 |  1
         4 | Hat     | Step A        | <em>null</em>                        |  1
...