Группировать по значению, если оно существует, иначе группировать по другому значению того же столбца - PullRequest
0 голосов
/ 22 января 2020

У меня есть такая таблица

|  Id  | ExternalId | Type |     Date    | StatusCode |
-------------------------------------------------------
|  1   |   123      |  25  |  2020-01-01 |      A     |
|  2   |   123      |  25  |  2020-01-02 |      A     |
|  5   |   125      |  25  |  2020-01-01 |      A     |
|  6   |   125      |  25  |  2020-01-02 |      B     |
|  3   |   124      |  25  |  2020-01-01 |      B     |
|  4   |   124      |  25  |  2020-01-02 |      A     |

Мне нужно взять только одну строку для каждого ExternalId, имеющего Max(Date) и имеющего StatusCode = B, если B существует, в противном случае StatusCode = A

Итак, ожидаемый результат:

|  Id  | ExternalId | Type |     Date    | StatusCode |
-------------------------------------------------------
|  2   |   123      |  25  |  2020-01-02 |      A     | <--I take Max Date and the StatusCode of the same row
|  6   |   125      |  25  |  2020-01-02 |      B     | <--I take Max Date and the StatusCode of the same row
|  3   |   124      |  25  |  2020-01-02 |      B     | <--I take Max Date and B, even if the Status code of the Max Date is A

Вот запрос, который я пытался написать:

SELECT ExternalId, Type, EntityType, Max(Date) as Date
From MyTable
group by ExternalId, Type, EntityType

Но я не могу закончить sh it.

Ответы [ 4 ]

1 голос
/ 22 января 2020

Если я понимаю ваши требования, это может быть то, что вы хотите:

SELECT ExternalId, Type,  MAX(Date) AS Date, MAX(StatusCode) AS StatusCode
FROM MyTable
GROUP BY ExternalId, Type

Объяснение :

Вы хотите, чтобы Max of StatusCode, потому что B является больше, чем A. Вы хотите, чтобы Max of Date, независимо от того, какой StatusCode отображается. И вы хотите это для каждого ExternalId. Следовательно, вам нужно сгруппировать по ExternalId.

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

0 голосов
/ 22 января 2020

Вот запрос, который может вам помочь.

SELECT Externalid, MAX([Date]) as 'Date', MAX(StatusCode) 'StatusCode' from MyTable Group by Externalid

В ожидаемом результате вы добавили столбец id , который не может быть добавлен здесь, если вы хотите иметь значения из нескольких строк.

Результат будет

|123|2020-01-02|A|
|124|2020-01-02|B| 
|125|2020-01-02|B|
0 голосов
/ 22 января 2020

Вы хотите фильтровать вместо совокупности. Одним из решений является использование row_number():

select *
from (
    select 
        t.*,
        row_number() over(partition by ExternalId order by StatusCode desc, Date desc) rn
    from mytable t

) t
where rn = 1

Предложение order by из row_number() сначала ставит строки с StatusCode = 'B', а затем упорядочивает их по убыванию.

Это работает, потому что StatusCode имеет только два значения, и потому что 'B'> 'A'. Если ваши реальные данные имеют разные значения (или более двух значений), вам потребуется нечто более явное, например:

order by case when StatusCode = 'B' then 0 else 1 end, Date desc
0 голосов
/ 22 января 2020

Насколько я понимаю из вашего sql, вам также нужно сгруппировать по типу и EntityType. Если это правильно, вы можете написать max с условием для 'B' и другой max для всех строк и использовать эти результаты в функции isnull или coalesce, например:

Select
 t.ExternalId
,t.Type
,t.EntityType
,isnull(
  max(iif(t.StatusCode='B', t.Date, null))
 ,max(t.Date)
) as Date
From MyTable t
Group by 
 t.ExternalId
,t.Type
,t.EntityType
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...