如何在 Oracle SQL 中不使用 distinct 选择从多个 max(case when) 派生的唯一行

Posted

技术标签:

【中文标题】如何在 Oracle SQL 中不使用 distinct 选择从多个 max(case when) 派生的唯一行【英文标题】:How to select a unique row derived of multiple max(case when) without using distinct in Oracle SQL 【发布时间】:2019-02-05 06:35:14 【问题描述】:

我需要为每个 ID 选择不同文档的最近上传日期,并且我希望每个 ID 只有一行。

我目前在做什么:

SELECT DISTINCT id,
                tree_date,
                sun_date
FROM
  (SELECT id,
          max(CASE
                  WHEN doc_name LIKE 'tree%' THEN upload_date 
                            END) OVER (PARTITION BY id ORDER BY id) tree_date,
          max(CASE WHEN doc_name LIKE 'sun%' THEN upload_date
                            END) OVER (PARTITION BY id ORDER BY id) sun_date
   FROM documents
   WHERE doc_name LIKE 'tree%'
     OR doc_name LIKE 'sun%' )

此查询有效并为我提供了我想要的结果,但我不相信我正在以最有效的方式选择每个 ID 的文档的最大上传日期。任何人都可以提出一种更有效的方法,而不是明显的,因为我相信这会大大减慢查询速度。

感谢任何帮助。如果需要更多信息,请告诉我。

【问题讨论】:

嗨,如果您有一个文档类型列(例如 doc_type 值是 = 树、太阳、月亮、河流、花 .. 等等),那么您可以在 doc_type 列上进行分组并选择最大值(上传日期) 【参考方案1】:

您只是想要条件聚合吗?

SELECT id,
       MAX(CASE WHEN doc_name LIKE 'tree%' THEN upload_date END) as tree_date,
       MAX(CASE WHEN doc_name LIKE 'sun%' THEN upload_date END) as sun_date
FROM documents
WHERE doc_name LIKE 'tree%' OR
      doc_name LIKE 'sun%'
GROUP BY id;

【讨论】:

谢谢,看来答案很简单。我需要对每种类型的文档进行分组而不是分区。【参考方案2】:

使用row_number窗口函数

      select * 
      from (
     select id,doc_name,
     row_number() over(partition by id,doc_name order by upload_date desc) n

     from documents where doc_name like 'tree%' or doc_name like 'sun%'
      ) t where t.rn=1

【讨论】:

【参考方案3】:

您可以尝试使用 row_number()

select * from 
(
select id, row_number() over(partition by doc_name,id order by upload_date desc) as rn
from documents
where doc_name like 'tree%' or doc_name like 'sun%'
A where rn=1

【讨论】:

以上是关于如何在 Oracle SQL 中不使用 distinct 选择从多个 max(case when) 派生的唯一行的主要内容,如果未能解决你的问题,请参考以下文章

Oracle在查询Sql中不使用order by,导致数据量足够大的时候同样的sql查询的结果顺序不同?

Oracle - PLS-00642:SQL 语句中不允许本地集合类型

count(distinct) over (partition by... 在 Oracle SQL 中不起作用

在 PL/SQL Developer 中运行的日期查询显示时间,但在 Oracle SQL Developer 中不显示

日期计算在 Oracle SQL 案例语句中不起作用?

FROM 中的子查询在 Oracle SQL 中不起作用