2013-08-19 2 views
0

Предположим, у меня есть таблица (соотношение), какКак написать sql для этого случая?

MyTab(ID1,ID2,IsMarked, data,....) 

образец данных может быть, выглядит следующим образом:

1, 1, 1, ... 
1, 2, 0, ... 
1, 3, 0, ... 

2, 34, 1, ... 

3, 4, 0, ... 

4, 546, 0, ... 
4, 8, 0, ... 

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

Для этих выборочных данных, то результат должен быть:

1, 1, 1, ... 

2, 34, 1, ... 

3, 4, 0, ... 

4, 546, 0, ... 

Союз может быть решением, но это слишком долго и может иметь плохую производительность. Моя идея состоит в том, чтобы сортировать данные по ID1 и IsMarked desc, получить первый 1 для каждого ID1, но как написать SQL для этого случая?

+3

* Если нет makred записи, получить первый *, как вы заказываете эти строки ?, откуда вы знаете, какая строка первая? – Lamak

+0

Возможно ли, чтобы один ID1 имел несколько наборов IsMarked? Например. данные могут выглядеть как 1,1,1 ... 1,2,1 ... –

ответ

0

Выстрел в темноте:

SELECT A.* 
FROM MYTAB A 
    LEFT JOIN (
     SELECT MAX(ID2) AS MAXID2, ID1 
      FROM MYTAB 
       WHERE ISMARKED=1 
        GROUP BY ID1 
    ) B ON A.ID2=B.MAXID2 AND A.ID1=B.ID1 
     LEFT JOIN (
      SELECT MAX(ID2) AS MAXID2, ID1 
       FROM MYTAB 
        WHERE ISMARKED=0 
         GROUP BY ID1 
     ) C ON A.ID2=C.MAXID2 AND A.ID1=C.ID1 
      WHERE 
       (B.ID1 IS NOT NULL) 
       OR 
       (B.ID1 IS NULL AND C.ID1 IS NOT NULL); 
3

Для Только один может быть отмечен для каждого ID1 должно работать:

;with cte as (
    select *, rn=row_number() over (partition by ID1 order by IsMarked desc) 
) 
select * 
from cte 
where rn=1 
Смежные вопросы