如何分组使用存在

时间:2014-01-27 20:21:54

标签: sql teradata

我有下表

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 个答案:

答案 0 :(得分:11)

你真的需要使用EXISTS吗?

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

答案 1 :(得分:2)

您可以使用WITH子句来实现相同的效果:

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 |
+----------+--------+--------------+

你采取独特的人格,才能获得最终结果。

类似于使用存在的解决方案是:

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)