【问题标题】:Oracle - Select rows Group By based on multiple columnsOracle - 根据多列选择行分组依据
【发布时间】:2020-11-19 00:29:13
【问题描述】:

我想获取特定日期和时间的重复行,按 bnametxn_date 分组 AND txn_date 最多小时和分钟(秒不需要匹配)

例如,我获取下面的行 txn_date = 2020/07/28txn_type = OPDpayment_mode = CREDITinv_numAGL 开头

其中,我只想要 ID 为 1 - 4 的行

ID |         txn_date       |   bname        
-----------------------------------------------
 1 | 2020/07/28 10:21:58 PM |  MRS R A W B VERNON
 2 | 2020/07/28 10:21:56 PM |  MRS R A W B VERNON
 3 | 2020/07/28 09:51:58 AM |  MRS TRIDENTZ
 4 | 2020/07/28 09:51:58 AM |  MRS TRIDENTZ
 5 | 2020/07/28 09:49:51 AM |  MRS TRIDENTZ
 6 | 2020/07/28 08:33:14 AM |  MRS TRIDENTZ
 7 | 2020/07/28 08:25:06 AM |  MRS S F D SHERILA
 8 | 2020/07/28 08:11:35 AM |  MRS S F D SHERILA

我在下面使用这个查询。

select to_char(l.txn_date,'YYYY/MM/DD HH12:MI:SS AM') "DATE",l.bname
from linv l where (bname) IN (select bname from linv
where txn_date like '28-JUL-20%'
group by bname, txn_date
having count(*) > 1) and l.txn_type = 'OPD' and payment_mode = 'CREDIT' 
and inv_num like 'AGL%' 
and txn_date like '28-JUL-20%'
order by l.txn_date desc, l.bname

但这并没有给我想要的输出,因为一些必需的行没有被获取。

我尝试将 group by 更改为 to_char(txn_date, 'HH24'),但这也没有用。

我认为group_by txn_date 有问题但无法修复。有人可以帮忙吗?

谢谢!

【问题讨论】:

  • 你想要什么结果?
  • 我做了一些修改并指定了我想要的结果

标签: sql oracle select group-by


【解决方案1】:

如果您尝试根据最新的日期时间进行分组,您可以使用 TRUNC 函数去除秒和毫秒。

https://docs.oracle.com/cd/B28359_01/server.111/b28286/functions209.htm#SQLRF06151

改为在你的组中使用它

group by bname, to_char(TRUNC(txn_date, 'MI'), 'DD-MON-YYYY HH24:MI:SS')

【讨论】:

  • 谢谢!我有一个问题,假设有 3 行 bnameXtxn_datedate1-time1。另一行 bnameXtxn_datedate1-time2。是否可以获取所有 4 行?我正在经历这种情况
  • 如果 time1time2 最多(不包括)秒数相同,那么是的。这就是 TRUNC(.., 'MI)) 在分钟后截断所有细节(秒、毫秒)的目的。
【解决方案2】:

exists 做你想做的事吗?

select l.*
from linv l
where exists (select 1
              from linv l2
              where trunc(l2.txn_date) = trunc(l.txn_date) and
                    l2.bname = l.bname
             );

您也可以添加其他过滤器。您的查询建议:

with l as (
      select l.*
      from linv l
      where l.txn_type = 'OPD' and
            l.payment_mode = 'CREDIT' and
            l.inv_num like 'AGL%' 
            l.txn_date >= date '2020-07-28' and
            l.txn_date < date '2020-07-29' 
           )
select l.*
from l l
where exists (select 1
              from l l2
              where trunc(l2.txn_date) = trunc(l.txn_date) and
                    l2.bname = l.bname
             );

或者使用窗口函数:

with l as (
      select l.*
      from linv l
      where l.txn_type = 'OPD' and
            l.payment_mode = 'CREDIT' and
            l.inv_num like 'AGL%' 
            l.txn_date >= date '2020-07-28' and
            l.txn_date < date '2020-07-29' 
     )
select l.*
from (select l.*, count(*) over (partition by trunc(txn_date), bname) as cnt
      from l
     )l
where cnt >= 2;

【讨论】:

  • 谢谢先生,我想试一试exists 并使用了第二个示例,但它获取了where 子句的所有行
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-25
  • 2022-11-30
相关资源
最近更新 更多