2015-09-09 3 views
3

КодT-SQL | Найти кратные (с закруткой ?!)

CREATE TABLE #Temp (ValA varchar(10) NULL, FK_ID int) 
INSERT INTO #Temp 
SELECT 'A',1 
UNION ALL 
SELECT 'A',1 
UNION ALL 
SELECT 'A',1 
UNION ALL 
SELECT 'A',2 
UNION ALL 
SELECT 'B',1 
UNION ALL 
SELECT 'B',2 
UNION ALL 
SELECT 'C',1 
UNION ALL 
SELECT 'C',1 
UNION ALL 
SELECT 'C',1 

SELECT 
ValA 
, FK_ID 
, CASE WHEN COUNT(*) OVER (PARTITION BY ValA, FK_ID) > 1 THEN 1 
     ELSE 0 
    END IsMultiple 
FROM #Temp 

DROP TABLE #Temp 

Токовый выход

ValA FK_ID IsMultiple 
A 1 1 
A 1 1 
A 1 1 
A 2 0 
B 1 0 
B 2 0 
C 1 1 
C 1 1 
C 1 1 

Желаемая Выход

ValA FK_ID IsMultiple 
A 1 1 
A 1 1 
A 1 1 
A 2 **1** 
B 1 0 
B 2 0 
C 1 1 
C 1 1 
C 1 1 

Цель Я хотел бы найти кратные секционированных по Валу и FK_ID но для тех, где ValA повторяется, и по крайней мере 2 из FK_ID повторяется (хотя, по крайней мере, один другой нет), мне бы хотелось, чтобы те t o быть отмечен как 1 (IsMultiple).

т.е. Вал - А имеет 4 записи, в которых 3 записи имеют такое же FK_ID, но один другой FK_ID, Весь комплект должен быть помечен как IsMultiple = 1

Спасибо

ответ

4

Если вы не имеете NULL значение в FK_ID

SELECT 
ValA 
, FK_ID 
, CASE WHEN COUNT(*) OVER (PARTITION BY ValA) > 
     dense_rank() OVER (PARTITION BY ValA ORDER BY FK_ID ASC) + dense_rank() OVER (PARTITION BY ValA ORDER BY FK_ID DESC) -1 -- Get Distinct FK_ID Count 
     THEN 1 
     ELSE 0 
    END IsMultiple 
FROM Temp 
+1

Хорошо, только вы тоже поддержали :) – Shiva

+0

Логика в создании этого запроса довольно больна. Благодарю. так как я немного разбираюсь в этом запросе, если мне нужно сделать ValA = A установленным как 0 для IsMultiple, как бы мне это изменить? (глядя на индивидуальную агрегацию fx's). – 007

+0

рейтинг fx's *: D – 007

3

Не очень элегантный, но работает:

select 
    t.*, 
    case when tex.ValA is null 
     then 0 
     else 1 
    end IsMultiple 
from #Temp t 
left join (
    select 
     ValA 
    from #Temp 
    group by 
     ValA, FK_ID 
    having 
     count(*) > 1 
) tex on 
    t.ValA = tex.ValA 

Здесь во внутреннем запросе мы выбираем Вейлас, которые имеют несколько одинаковых пары (Вал, FK_ID) - это достигнуто путем группировки на (Вале, FG_ID) и принимая только с having count(*) > 1.
Затем в левом соединении мы используем этот набор для отметки записей с соответствующими ValAs как IsMultiple.

+1

Ahh, делает намеченную работу. Кроме того, большое спасибо за xplanaiton, помогающий мне понять. Ура! – 007

0

Это говорит о том, какие значения ValA несколько используют то, что вы уже сделали.

SELECT 
    a.ValA 
    ,CONVERT(BIT,sum(IsMultiple)) 
FROM (
    SELECT 
     ValA 
    , FK_ID 
    , CASE WHEN COUNT(*) OVER (PARTITION BY ValA, FK_ID) > 1 THEN 1 
      ELSE 0 
     END IsMultiple 
    FROM #Temp 
) a 
group by a.ValA 
+0

Это правильно и намеренно. Я вижу желаемый результат, но взял некоторые свободы, поскольку информация, которую нужно знать, действительно показывает мой запрос. – UnhandledExcepSean

+0

Спасибо за ваш вклад, это может пригодиться дальше по линии. Ура! – 007

Смежные вопросы