2015-10-01 3 views
1

Привет всем рассмотреть следующий в моей таблице структуруКак выбрать строки с колонкой, содержащей предусмотренных значениями

Col1 Col2 Col3 
A  1 Aa 
A  2 Bb 
A  1 Aa 
A  4 Bb 
B  2 Bb 
C  1 Aa 
C  5 Bb 
D  3 Aa 

Как вы можете видеть Col3 содержит distint значения Aa и Bb.

Я пытаюсь написать запрос, который возвращает только строки с Col1 со значениями Aa и Bb (Both) или Aa (Alone).

Точка - удалить те строки, которые имеют только Bb, связанные с определенным значением Col1.

Пример - для Col1. Значительное значение A должно иметь Aa и Bb/Aa в соответствующем Col3. Это требование нарушается величиной В в Col1, следовательно, привести набор не должен быть связан с рядами B.

Ожидаемый результат -

Col1 Col2 Col3 
A  1 Aa 
A  2 Bb 
A  1 Aa 
A  4 Bb 
C  1 Aa 
C  5 Bb 
D  3 Aa 
+0

Я думаю, что я больше запутывается тем, как вы сформулировать свой вопрос, чем то, что вы пытаетесь достичь. Как может Col1 иметь значение Aa, когда в вашем примере он имеет только одиночные значения символа ??? – mituw16

+0

Я только что отредактировал свои слова, чтобы сделать его более понятным. – NewBee

ответ

7
SELECT * 
FROM TableName T 
WHERE EXISTS (SELECT 1 
       FROM TableName 
       WHERE T.Col1 = Col1 
       AND Col3 = 'Aa') 
+0

Спасибо, что он отлично работает, можете немного объяснить этот вопрос. Просто, если я хочу только те значения, которые имеют только Aa и Bb. Тогда какая модификация запроса будет работать? – NewBee

2

Еще один подход заключается в использовании intersect и union.

Fiddle with sample data

select * from t where col1 in (
select col1 from t where col3 = 'Aa' 
intersect 
select col1 from t where col3 = 'Bb' 
union 
select col1 from t where col3 = 'Aa') 
0

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

Select 
T.* 
From 
(Select 
    'A' As Col1, 1 As Col2, 'Aa' As Col3 
Union All 
Select 
    'A', 2, 'Bb' 
Union All 
Select 
    'A',1,'Aa' 
Union All 
Select 
'A',4,'Bb' 
Union All 
Select 
'B',2,'Bb' 
Union All 
Select 
'C',1,'Aa' 
Union All 
Select 
'C',5,'Bb' 
Union All 
Select 
'D',3,'Aa' 
) T 
Inner Join 
(Select 
    Col1 
    ,Sum(Case When Col3 = 'Aa' Then 1 Else 0 End) As CountAa 
From 
    (Select 
     'A' As Col1, 1 As Col2, 'Aa' As Col3 
    Union All 
    Select 
     'A', 2, 'Bb' 
    Union All 
    Select 
     'A',1,'Aa' 
    Union All 
    Select 
    'A',4,'Bb' 
    Union All 
    Select 
    'B',2,'Bb' 
    Union All 
    Select 
    'C',1,'Aa' 
    Union All 
    Select 
    'C',5,'Bb' 
    Union All 
    Select 
    'D',3,'Aa' 
    ) T2 
Group By 
    Col1 
) T3 On T.Col1 = T3.Col1 
Where 
T3.CountAa > 0 

Упрощенное с таблицей, то будет:

Select 
T.* 
From 
YourTable T 
Inner Join 
(Select 
    Col1 
    ,Sum(Case When Col3 = 'Aa' Then 1 Else 0 End) As CountAa 
From 
    YourTable T2 
Group By 
    Col1 
) T3 On T.Col1 = T3.Col1 
Where 
T3.CountAa > 0 

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

+0

Спасибо, но это будет громоздкая работа для миллионов строк. – NewBee

+2

Я не могу представить ни одной ситуации в реальном мире, где жесткая кодировка из 30 + строк sql побила бы уже предоставленный ответ. – mituw16

+1

Я определенно согласен. Это то, что мой мозг придумал сперва ... –

0
Select table1.Col1, table1.Col2, table1.Col3 
From Table1 
join (SELECT Col1 
     ,SUM(case when col3 = 'Aa' then 1 when Col3 = 'Bb' then 0 end) AS [Counting] 
     FROM [dbo].[Table1] 
     group by Col1 
     having SUM(case when col3 = 'Aa' then 1 when Col3 = 'Bb' then 0 end) > 0) keep on table1.Col1 = keep.Col1 
+0

Можете ли вы объяснить, как это отличается/лучше, чем принятый ответ? –

0

В зависимости от того, что ваши фактические данные выглядит, row_number() может быть другая возможность:

select Col1, Col2, Col3 
from (
    select *, i = row_number() over(partition by Col1 order by Col1, Col3) 
    from TableName 
) a 
where i > 1 or Col3 like 'Aa' 
Смежные вопросы