【问题标题】:SQL - Conditional SelectionSQL - 条件选择
【发布时间】:2018-03-08 03:43:18
【问题描述】:

我正在尝试构建一个 Oracle SQL 查询,其中我选择的用户至少包含一个许可证 =“+”,而所有默认组织 =“-”。换言之,选择具有没有默认组织的许可证的用户。在下面的示例中,我希望只有 Annete 会显示在结果中。

Table_Users:用户、许可

Table_Organizations:Default_Org、Org_Name

下面的查询没有返回结果:

select User 
from Table_Users, Table_Organizations 
where Table_Users.User = Table_Organizations.UsrX 
and (Default_Org = '+' and Default_Org = '-')*

【问题讨论】:

  • (Default_Org = '+' and Default_Org = '-') ??? (license= '+' and Default_Org = '-')

标签: sql oracle conditional relational-database contain


【解决方案1】:
select User 
from Table_Users, Table_Organizations 
where Table_Users.User = Table_Organizations.UsrX 
and License = '+' and Default_Org = '-'

【讨论】:

  • 虽然这指出了帖子的一个明显的代码问题,但它实际上并没有回答他试图找到哪些没有默认组织的用户。你目前写的答案会返回 jeff,即使他有一个默认组织
  • 我不同意@Matt,也许您应该使用提供的数据运行上述代码
  • 您对上述数据是正确的,它将返回 OP 所说的内容,但我认为在查看上述数据时,OP 还遗漏了一些案例,包括 Jeff License = '+' 和 default_org = '-' 如果存在这种情况,则此查询将返回 Jeff 但这不是我们所希望的,因为另一行有一个 default_org
  • @Matt 我猜不出桌子上的其他数据 ;))
  • 您可以就 OP 做错了什么和/或您如何修复它提供一些评论。答案不仅有利于提问者,也可供他人学习。
【解决方案2】:
SELECT
    u.User
FROM
    Table_Users u
    INNER JOIN Table_Organizations o
    ON u.User = o.Usrx
GROUP BY
    u.User
HAVING
    COUNT(CASE WHEN License = '+' THEN 1 END) > 0
    AND COUNT(CASE WHEN Default_Org = '+' THEN 1 END) = 0

首先,我建议使用显式连接而不是隐式连接,这是我的一个小烦恼,我认为这个网站上的其他一些人,因为显式连接多年来一直是 ANSI SQL 标准的一部分。

就您真正想要的技术而言,称为条件聚合。通过只计算您要查找的值,您可以在 HAVING 子句中使用它们来排除您不想要的记录。

注意COUNT(CASE WHEN... THEN END) 会起作用,因为只有您想要的值才会被计算在内,任何不满足该条件的值都将为 NULL,因此不会被计算在内。

因为我不知道哪个表上有许可证,所以你也可能使用如下:

SELECT
    u.User
FROM
    Table_Users u
WHERE
    u.License = '+'
    AND NOT EXISTS(SELECT 1 FROM Table_Organizations o WHERE u.User = o.Usrx AND Default_Org = '+')

【讨论】:

    【解决方案3】:

    Knowing + 先于 - 我们可以使用最小聚合。这假定许可证和默认组织只能具有“+”或“-”值。

    With cte ("user", license, default_org, org_name) as  (
    SELECT 'Jeff','+','+', 'Org 1' FROM DUAL UNION ALL
    SELECT 'Jeff','-','-', 'Org 2' FROM DUAL UNION ALL
    SELECT 'Jeff','-','-', 'Org 3' FROM DUAL UNION ALL
    SELECT 'Annete','+','-', 'Org 4' FROM DUAL UNION ALL
    SELECT 'Annete','-','-', 'Org 5' FROM DUAL)
    
    SELECT "user", min(license), Min(default_org) 
    FROM CTE A
    GROUP BY "user"
    HAVING min(license) = '+' 
       AND min(Default_org) = '-';
    

    如果 license 和 default_org 都有用户索引;这会很快。

    【讨论】:

      猜你喜欢
      • 2010-11-05
      • 2017-03-30
      • 1970-01-01
      • 2021-09-11
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-04
      相关资源
      最近更新 更多