【问题标题】:Nested Oracle SQL - Multiple Values嵌套 Oracle SQL - 多个值
【发布时间】:2016-05-20 11:02:17
【问题描述】:

我有一个类似的表结构:

Table = contact

Name    Emailaddress    ID
Bill    bill@abc.com    1
James   james@abc.com   2
Gill    gill@abc.com    3

Table = contactrole

ContactID   Role
1           11
1           12
1           13
2           11
2           12
3           12

我想从第一个表中选择姓名和电子邮件地址,其中该人的角色为 12 但不是 11 或 13。在此示例中,它应该只返回 Gill。

我相信我需要一个嵌套的 SELECT,但很难做到这一点。我做了以下操作,但显然它不起作用并返回所有内容。

SELECT c.Name, c.Emailaddress FROM contact c
WHERE (SELECT count(*) FROM contactrole cr
       c.ID = cr.ContactID
       AND cr.Role NOT IN (11, 13)
       AND cr.Role IN (12)) > 0

【问题讨论】:

    标签: sql oracle select nested


    【解决方案1】:

    您可以使用EXISTSNOT EXISTS 的组合

    SELECT *
    FROM contact c
    WHERE
        EXISTS(SELECT 1 FROM contactrole cr WHERE cr.ContactID = c.ID AND cr.Role = 12)
        AND NOT EXISTS(SELECT 1 FROM contactrole cr WHERE cr.ContactID = c.ID AND cr.Role IN(11, 13))
    

    另一种选择是使用GROUP BYHAVING

    SELECT c.*
    FROM contact c
    INNER JOIN contactrole cr
        ON cr.ContactID = c.ID
    GROUP BY
        c.ID, c.Name, c.Emailaddress
    HAVING 
        SUM(CASE WHEN cr.Role = 12 THEN 1 ELSE 0 END) > 0
        AND  SUM(CASE WHEN cr.Role IN(11, 13) THEN 1 ELSE 0 END) = 0
    

    【讨论】:

      【解决方案2】:

      Having 子句中使用条件聚合来过滤记录

      试试这个

      SELECT c.NAME, 
             c.emailaddress 
      FROM   contact c 
      WHERE  id IN (SELECT contactid 
                    FROM   contactrole 
                    GROUP  BY contactid 
                    HAVING Count(CASE WHEN role = 12 THEN 1 END) > 1 
                           AND Count(CASE WHEN role in (11,13) THEN 1 END) = 0)
      

      如果你在role 中只有11,12,13,那么使用可以使用这个

      SELECT c.NAME, 
             c.emailaddress 
      FROM   contact c 
      WHERE  id IN (SELECT contactid 
                    FROM   contactrole 
                    GROUP  BY contactid 
      HAVING Count(CASE WHEN role = 12 THEN 1 END) = count(*)
      

      【讨论】:

      • 甜蜜!干杯@Prdp :)
      【解决方案3】:

      您可以使用 JOIN 来做到这一点:

      SELECT c.*
        FROM CONTACT c
        INNER JOIN CONTACTROLE cr12
          ON cr12.CONTACTID = c.ID AND
             cr12.ROLE = 12
        LEFT OUTER JOIN CONTACTROLE cr11
          ON cr11.CONTACTID = c.ID AND
             cr11.ROLE = 11
        LEFT OUTER JOIN CONTRACTROLE cr13
          ON cr13.CONTACTID = c.ID AND
             cr13.ROLE = 13
        WHERE cr11.ROLE IS NULL AND
              cr13.ROLE IS NULL
      

      INNER JOIN CONTACTROLE cr12要求角色 12 存在于给定的联系人 ID; LEFT OUTER JOIN CONTACTROLE cr11LEFT OUTER JOIN CONTRACTROLE cr13 检查角色 11 和 13 可能是否存在给定的联系人 ID; WHERE 子句验证角色 11 或 13 都不存在。

      祝你好运。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-10-14
        • 1970-01-01
        • 2011-12-17
        • 1970-01-01
        • 2016-03-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多