2014-01-27 3 views
1

я следующая таблицаКак группа, используя существует

personid talent 
1  swim 
2  play 
1  play 
1  swim 
2  play 
3  swim 
3  swim 
2  play 

Так человек 1 может одновременно плавать и играть. Человек 2 может играть только. Человек 3 может плавать.

мне нужно получить следующий результат

personid talent 
1  both 
2  play 
3  swim 

Как я могу сделать это с помощью exists?


Я попытался

SELECT DISTINCT personid, 
CASE WHEN (EXISTS(
SELECT * FROM mytable 
-- I got stuck 

PS: У меня есть длинный решение, которое работает. , Но мне не нравится, потому что это долго

SELECT DISTINCT dis2.personid , CASE WHEN talcount = 2 THEN 'both' 
ELSE talent END AS talent 
FROM 
(
SELECT personid , COUNT(talent) talcount 
FROM 
(
SELECT DISTINCT personid , talent 
FROM my_table 
) AS dis 
GROUP BY personid 
) dis2 
JOIN my_table dis3 
ON dis2.personid = dis3.personid 

ответ

2

Вы можете использовать с пунктом для достижения того же эффекта:

WITH 
    DISTINCT_TALENTS(PERSONID, TALENT) AS 
    (SELECT DISTINCT PERSONID, TALENT 
    FROM TALENTS) 
SELECT DISTINCT PERSONID, TALENT 
FROM 
    (SELECT A.PERSONID, 
    CASE WHEN TALENT_COUNT = 2 THEN 'BOTH' ELSE A.TALENT END 
    FROM 
    DISTINCT_TALENTS A 
    INNER JOIN 
    (SELECT PERSONID, COUNT(TALENT) TALENT_COUNT 
     FROM DISTINCT_TALENTS 
     GROUP BY PERSONID) B 
    ON A.PERSONID = B.PERSONID) 

Сначала вы создаете виртуальную DISTINCT_TABLES таблицу:

+------------------+ 
| personid talent | 
+------------------+ 
| 1  play | 
| 1  swim | 
| 2  play | 
| 3  swim | 
+------------------+ 

Далее вы создаете подзапрос b со следующими

+------------------------+ 
| personid talent_count | 
+------------------------+ 
| 1  2    | 
| 2  1    | 
| 3  1    | 
+------------------------+ 

вы присоединитесь с оригинальным DISTINCT_TALENTS получить

+----------+--------+--------------+ 
| personid | talent | talent_count | 
+----------+--------+--------------+ 
|  1 | both |   2 | 
|  1 | both |   2 | 
|  2 | play |   1 | 
|  3 | swim |   1 | 
+----------+--------+--------------+ 

вы берете отчетливое PersonId, талант, чтобы получить конечный результат.

Решение аналогично использованию существует, является:

SELECT DISTINCT PERSONID, TALENT 
    FROM 
    (
    SELECT 
     B.PERSONID, 
     CASE 
     WHEN A.TALENT IS NULL THEN 'swim' 
     WHEN B.TALENT IS NULL THE 'play' 
     ELSE 'both' 
     END TALENT 
    FROM 
     TALENTS A 
    FULL OUTER JOIN 
     TALENTS B 
    ON A.PERSONID = B.PERSONID 
    AND A.TALENT='play' 
    AND B.TALENT='swim' 
) 

И, наконец, также с функцией EXISTS используется как функция поиска:

SELECT DISTINCT PERSONID, TALENT 
FROM (
    SELECT A.PERSONID, 
     CASE 
      WHEN A.TALENT = 'play' AND EXISTS (SELECT 1 FROM TALENTS B WHERE A.PERSONID = B.PERSONID AND B.TALENT = 'swim') 
      THEN 'both' 
      WHEN A.TALENT = 'swim' AND EXISTS (SELECT 1 FROM TALENTS B WHERE A.PERSONID = B.PERSONID AND B.TALENT = 'play') 
      THEN 'both' 
      ELSE 
      A.TALENT 
     END TALENT 
FROM 
TALENTS A) 
+0

+1 Благодарим за внимание. У меня есть аналогичное решение. Я опубликовал его. Я использовал DISTINCT, COUNT. , , Я надеялся получить краткое решение с помощью «EXISTS» – Buras

+0

Добавлено решение с чем-то похожим на существующее: оно может быть написано с помощью существующего, но оно действительно более эффективно, если вы хотите, я могу записать его –

+0

Спасибо. Пожалуйста, добавьте решение 'exist' – Buras

11

вам действительно нужно использовать EXISTS ли?

SELECT 
    personid, 
    CASE 
     WHEN COUNT(DISTINCT talent) = 2 THEN 'both' 
     ELSE MIN (talent) 
    END 
FROM talents 
GROUP BY 1 
+0

Это лучшее решение _1 –

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