Как я могу поместить столбец в SQL, который показывает 1, если значение в другом столбце является уникальным, и 0, если он повторяется? - PullRequest
0 голосов
/ 05 апреля 2019

Я хотел бы построить столбец, в котором значение равно 1, если это первое вхождение значения в одной строке, и 0, если это не первое вхождение.

enter image description here

Ответы [ 3 ]

4 голосов
/ 05 апреля 2019

Вы можете использовать оконную функцию и CTE, чтобы назначить число строк каждому разделу «data», а затем установить флаг равным 1, если число строк равно 1 или 0.

Rextester Demo

Предполагается:

  • поле для оценки называется «Данные»
  • 1-я запись не считается дубликатом, если все остальные находятся.1-й здесь сложно, поскольку мы не определили порядок, поэтому первая запись, с которой сталкивается система, будет рассматриваться как не дублирующаяся;если только мы не определим порядок в функции окна;этот неповторяющийся объект может меняться от прогона к прогону.

.

With CTE AS (SELECT Data, Row_Number() over (partition by Data order by Data) RN 
             FROM TableName T)
SELECT Data, case when RN = 1 then 1 else 0 end as Flg
FROM CTE

Возвращает что-то подобное, если использовать мои данные примера:

    Data    Flg
1   A   1
2   A   0
3   B   1
4   B   0
5   B   0
6   C   1
7   C   0
0 голосов
/ 05 апреля 2019

Таблица SQL представляет неупорядоченные наборы.Ваша таблица не имеет достаточно информации, чтобы ответить на этот вопрос после ее создания.

Если у вас есть такая таблица, вы можете использовать такой запрос, чтобы присвоить значение:

select value,
       (case when row_number() over (partition by value order by ?) = 1
             then 1 else 0
        end) as flag
from t;

? - это заполнитель для столбца, например createdAt или id, который определяет порядок значений в таблице.

Если у вас нет столбцакоторый определяет порядок, вы можете сделать это с помощью триггера, который проверяет, существует ли значение уже.Однако вместо написания триггера я бы предложил создать таблицу со столбцом identity() или столбцом createdAt (или обоими), чтобы зафиксировать порядок вставки.

0 голосов
/ 05 апреля 2019

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

Вы можете использовать оконную функцию, такую ​​как LAG, чтобы проверить, существует ли предыдущее значение в наборе в соответствии с заданным вами порядком поиска, например:

declare @t table (data varchar(10))
insert into @t
values ('A'),
    ('B'),
    ('A'),
    ('B'),
    ('B'),
    ('C'),
    ('C')


SELECT 
    Data, 
    iif( lag(1) over (partition by Data order by Data) is null,1,0) as Value
FROM @t

Это вернет:

Data    Value
A       1
A       0
B       1
B       0
B       0
C       1
C       0

lag(1) over (partition by Data order by Data) разбивает строки по значениям в столбце данных и сортирует их по одному значению, в результате чего получается случайный порядок. Затем он возвращает «предыдущее» значение для этого раздела. Для первой строки ее нет, а LAG возвращает null.

iif( ... is null,1,0) as Value проверяет результат и возвращает 1, если он нулевой, в противном случае 0.

Если вы хотите сохранить изменения в таблице, вы можете использовать обновляемый CTE:

declare @t table (data varchar(10),value bit)
insert into @t(data)
values ('A'),
    ('B'),
    ('A'),
    ('B'),
    ('B'),
    ('C'),
    ('C');


with x as ( SELECT 
    Data,value, 
    iif( lag(1) over (partition by Data order by Data) is null,1,0) as Val
FROM @t)
update x
set value=val
from @t;

select * 
from @t
order by data

Вы можете использовать триггер на INSERT, UPDATE, DELETE, чтобы запускать этот запрос при каждой модификации и обновлять таблицу. Хотя было бы лучше сделать все изменения и выполнить UPDATE только в конце

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...