результат группового запроса, в который не включен флаг

0

У меня есть таблица, подобная этой

NAME    FLAG
---------------------------
abc     1
abc     0
abc     2
def     1
def     2
xyz     0
xyz     0
xyz     1
efg     1

Мне нужен запрос, который перечисляет имя (group the result), флаг которого не включен 0 и включал результат 1.The, как показано ниже:

NAME    FLAG
------------------
def     1
efg     1

Я пробовал запрос, но не тот же результат.

select * mytable where FLAG NOT IN (0) GROUP BY NAME;
  • 0
    Вы пробовали что-нибудь? Кроме того, ваше требование не ясно. Вы хотите включить имена с флагом 1 и без флага 0? Как сгруппированы результаты?
  • 0
    @clinomaniac yes .. выберите * mytable, где FLAG NOT IN (0) GROUP BY NAME; Но не получил результат
Теги:

3 ответа

0
Лучший ответ

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

SELECT * 
FROM mytable 
WHERE name NOT IN (SELECT name FROM mytable WHERE flag = 0)
    AND flag = 1;
0

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

SELECT t.name
  FROM a_table_like_this t
 GROUP BY t.name
HAVING MAX(t.flag=0) <> 1
   AND MAX(t.flag=1)  = 1

Выражения в предложении HAVING являются сокращением MySQL. Более эквивалентным стандартом ANSI будет:

SELECT t.name
  FROM a_table_like_this t
 GROUP BY t.name
HAVING MAX( CASE WHEN t.flag=0 THEN 1 ELSE 0 END) <> 1
   AND MAX( CASE WHEN t.flag=1 THEN 1 ELSE 0 END)  = 1

Чтобы лучше понять, что это делает, взгляните на то, как эти выражения оцениваются в каждой строке. Удалите предложение GROUP BY и переместите эти выражения в список SELECT...

SELECT t.name
     , t.flag
     , CASE WHEN t.flag=0 THEN 1 ELSE 0 END AS 'fl=0'
     , CASE WHEN t.flag=1 THEN 1 ELSE 0 END AS 'fl=1' 
  FROM a_table_like_this t
 ORDER
    BY t.name
     , t.flag

Мы получаем что-то вроде

name    flag  fl=0  fl=1
------  ----  ----  ----
abc     1     0     1
abc     0     1     0
abc     2     0     0
def     1     0     1
def     2     0     0
xyz     0     1     0
xyz     0     1     0
xyz     1     0     1
efg     1     0     1

Если мы теперь агрегируем эти строки по имени (GROUP BY name), мы можем использовать агрегат MAX() для выделения 1 (если она есть в группе, иначе мы вернем 0).

И мы можем сделать условные тесты по результатам агрегатных функций в предложении HAVING.

0

Таким образом вы можете использовать предложение NOT EXISTS.

select a.*
from tbl a
where not exists 
 (select *
  from tbl b
  where b.name=a.name 
   and b.flag=0)
and a.flag=1;

Ещё вопросы

Сообщество Overcoder
Наверх
Меню