一个 sql (oracle) 查询,用于获取每列具有两个不同(null 和非 null)值的唯一信息

Posted

技术标签:

【中文标题】一个 sql (oracle) 查询,用于获取每列具有两个不同(null 和非 null)值的唯一信息【英文标题】:one sql (oracle) query for getting unique information that has two different (null and not null) values per column 【发布时间】:2011-08-01 15:12:31 【问题描述】:

为清楚起见,foobar 表是结构化的,并且具有如下数据:

id、action_dt、status_id 1, '02-JUL-10', 'x' 1, '02-JUL-10', '2' 1, '02-JUL-10', 空 2, '02-JUL-10', 'a' 2, '02-JUL-10', 'b' 3, '02-JUL-10', 'k' 3, '02-JUL-10', 空 3, '03-JUL-10', 'k' 3, '03-JUL-10', 空

我需要一个获取 ID 的查询,以便每个 ID 每天都存在一个 NULL 值和一个 NOT NULL 值。因此,在上面的示例数据集中,查询需要返回:

'02-JUL-10', 1 '02-JUL-10', 3 '03-JUL-10', 3

是的,可以使用类似的方法来完成:

选择 nulls.action_dt , 空值.id 从(选择 action_dt , ID 来自 foobar 其中 status_id 为空 GROUP BY action_dt) 空值 内连接(选择 action_dt , ID 来自 foobar 其中 status_id 不为空 GROUP BY action_dt) non_nulls ON nulls.action_dt = non_nulls.action_dt AND nulls.id = non_nulls.id

但正如您所看到的,除其他外,还有两个子查询和另一个迭代迭代......

我一直在处理并希望得到的查询是以下形式:

选择 action_dt , ID 从 富吧 通过...分组 action_dt , ID , CASE WHEN status_id IS NOT NULL THEN 1 ELSE 0 END 拥有 计数(prim_card_nb)> 1

但它并没有完全返回我需要的内容(如您所知,HAVING 子句适用于正在查询的基础数据)。有什么想法吗?

毕竟,似乎一个解决方案是将上述查询放在子查询中并以这种方式过滤它,例如:

选择 action_dt , ID 从(选择 action_dt , ID 从 富吧 通过...分组 action_dt , ID , CASE WHEN status_id IS NOT NULL THEN 1 ELSE 0 END ) repeat_ids_per_day 通过...分组 action_dt , ID 拥有 计数(id)> 1

但我觉得它可以更好......

【问题讨论】:

虽然标记的答案对于我的具体问题是正确的,但由于实际项目的要求,这似乎是我必须在原始帖子中使用第一个查询,因为从gui,用户必须能够根据条件过滤报告。这个数据集被简化了,它不包含用户可以过滤的标准——所以通过将标准放在 WHERE 子句中似乎可行,但是 where 子句适用于整个数据集,而过滤条件需要应用到数据集的子集... 【参考方案1】:

您的想法是正确的:在这种情况下,您不需要子查询,聚合就足够了,应该更有效。这应该有效:

SQL> SELECT action_dt, id
  2    FROM foobar
  3   GROUP BY action_dt, ID
  4  HAVING COUNT(DISTINCT CASE WHEN status_id IS NULL THEN 1 ELSE 0 END) > 1;

ACTION_DT         ID
--------- ----------
02-JUL-10          1
02-JUL-10          3
03-JUL-10          3

【讨论】:

是的!你摇滚。我之前实际上已经使用过它,但我花了一段时间才明白它为什么起作用。在这里,我看到它为什么起作用并理解它,非常感谢。我也想投赞成票,但我没有帐户!【参考方案2】:

我认为您必须在您发布的第一个查询中做一些小改动

如下-

SELECT
    nulls.action_dt, nulls.id 

FROM        
(SELECT 
                action_dt
                , id        
            FROM        foobar 
            WHERE       status_id IS NULL
            GROUP BY    action_dt,id
uniou all
SELECT
                action_dt
                , id
            FROM        foobar 
            WHERE       status_id IS NOT NULL
            GROUP BY    action_dt,id)  
group by action_dt, id
having count(*) >1

您发布的内容不正确,如在 oracle 数据库中.. 选择时不能包含未分组的列名.. 所以请检查..这可能是你的错误..可能是问题的原因..

【讨论】:

感谢您的回答!您的答案是另一种解决方案,但与您修改的原始查询一样,它是一个低效的查询。 发布的查询不是原始查询.. 对.. 否则您不会在此处添加此问题.. 好吧,您犯了很多错误,作为老师,我应该指出学生的错误和替代方法...只需查看您发布的查询...它也不应该工作...那么这不是原始的...我只是复制它,因为我想为您提供有关您所做工作的指导

以上是关于一个 sql (oracle) 查询,用于获取每列具有两个不同(null 和非 null)值的唯一信息的主要内容,如果未能解决你的问题,请参考以下文章

如何使用单个 SQL 查询查找每列的最大值

Oracle SQL 排名查询

用于连接 Oracle 中多行的列值的 SQL 查询

oracle中的存储过程,用于根据行获取记录

oracle动态查询通过sql获取游标变量

用于 oracle 子查询的 Pyspark sql