Значения TSQL Coalesce Row - PullRequest
       5

Значения TSQL Coalesce Row

0 голосов
/ 14 февраля 2019

В настоящее время у меня есть очень простой запрос, который просто ВЫБИРАЕТ и производит следующее

| Date       | Name             | ID      |
|------------|------------------|---------|
| 2018-11-07 | McDonald's       | 1046226 |
| 2018-01-22 | NULL             | 1046226 |
| 2019-01-07 | Dell             | 1069285 |
| 2019-01-09 | Dell Corporation | 1069285 |

Что я хочу сделать, это ВЫБЕРИТЬ самую раннюю строку даты для каждого идентификатора, используя MIN

Но проблема у меня заключается в том, что если у самой ранней строки есть NULL-имя, я хочу объединить ее имя из другой строки

| Date       | Name             | ID      |
|------------|------------------|---------|
| 2018-01-22 | McDonald's       | 1046226 |
| 2019-01-07 | Dell             | 1069285 |

Я понятия не имею, есть ли здесь какой-нибудь синтаксис, который может мне помочь, может кто-нибудьпомочь?

Ответы [ 3 ]

0 голосов
/ 14 февраля 2019

Обычно для этого используется row_number():

select t.*
from (select t.*, row_number() over (partition by id order by date) as seqnum
      from <your query here> t
     ) t
where seqnum = 1;

Более простой метод, который может быть немного медленнее:

select top (1) with ties . . .
from . . .
. . .
order by row_number() over (partition by id order by date)
0 голосов
/ 14 февраля 2019

Два метода, протестированные в хранилище данных SQL Azure с использованием CTE

;WITH cte AS
(
SELECT *, ROW_NUMBER() OVER( PARTITION BY ID ORDER BY [Date] ) rn
FROM #tmp
)
SELECT [Date], name, ID 
FROM cte 
WHERE rn = 1

Или, если вы хотите перенести оставшиеся данные в новую таблицу, вы можете объединить CTE и CTAS в хранилище данных SQL Azure, например:

CREATE TABLE dbo.yourNewTable
WITH
(
    CLUSTERED COLUMNSTORE INDEX,
    DISTRIBUTION = HASH( ID )
    -- Optionally add partition scheme here if required
)
AS
WITH cte AS
(
SELECT
    [Date],
    MIN(Name) OVER( PARTITION BY ID ) name,
    ID,
    ROW_NUMBER() OVER( PARTITION BY ID ORDER BY [Date] ) rn
FROM dbo.yourTable
)
SELECT [Date], name, ID 
FROM cte 
WHERE rn = 1
OPTION ( LABEL = 'CTAS : Dedupe' );

Обратите внимание на разницу в поведении для RANK и ROW_NUMBER.

0 голосов
/ 14 февраля 2019

С coalesce:

select 
  min(t.date) Date,
  coalesce(
    (
      select name from tablename where id = t.id and date = (
        select min(date) from tablename where id = t.id
      )
    ),
    max(name)
  ) name,
  t.id ID
from tablename t
group by t.id
...