【问题标题】:Oracle SQL MAX and GROUP BY Costs too Much Lines of CodeOracle SQL MAX 和 GROUP BY 代码行数过多
【发布时间】:2022-12-18 22:10:39
【问题描述】:

我有一个很长的查询,我想在其中获取一些有关员工的数据:

SELECT e.id,
e.emp_number,
TO_CHAR(SYSDATE,'DD/MONTH/YYYY') "GREGORIAN",
to_char(sysdate,'DD-MM-YYYYY','nls_calendar=''arabic hijrah''') HIJRI,
ba.acc_number "Account Number"
to_char(c.id) "National ID",
en.name

FROM
  relationships r,
  rel_actions ra,
  actions a,
  payrolls p,
  emp_names en,
  citizenships c,
  pay_methods pm,
  bank_accounts ba,
  assignments as,
  emp e

WHERE r.id = ra.id
AND r.id=pm.id
AND as.id = e.id
AND r.id = e.id
AND en.id = e.id
AND en.NAME_TYPE ='GLOBAL'
AND a.action_type  = 'T'
AND a.id = ra.id
AND a.id = p.id
and c.id = e.id
and ba.id=pm.id
AND a.effective_date BETWEEN ba.start_date AND ba.end_date 
AND a.effective_date BETWEEN p.effective_start_date AND p.effective_end_date
AND a.effective_date BETWEEN r.start_date AND r.end_date
AND a.effective_date BETWEEN en.effective_start_date AND en.effective_end_date
AND a.effective_date BETWEEN e.effective_start_date AND e.effective_end_date
AND a.effective_date BETWEEN pm.effective_start_date AND pm.effective_end_date
AND a.effective_date BETWEEN as.effective_start_date AND as.effective_end_date
AND  as.assignment_type = 'E'
AND SYSDATE BETWEEN as.effective_start_date AND  as.effective_end_date

ORDER BY e.emp_number

这个查询的结果将是这样的:

emp_number      account_number      name      national_id       gregorian         hijri           

1               6456                john      ^*&$^**$^**       6/12/2022         12/5/1444
1               6456                john      ^*&$^**$^**       6/12/2022         12/5/1444
2               4121                Mathew    %&#%^%&%&%^       6/12/2022         12/5/1444
2               4121                Mathew    %&#%^%&%&%^       6/12/2022         12/5/1444

以前两行为例,它们有不同的effective_date,所以我想获取具有最新日期的行并消除重复:

and a.effective_date in (
select effective_Date from pay_payroll_actions 
where  a.effective_date BETWEEN ba.start_date AND ba.end_date 
AND a.effective_date BETWEEN p.effective_start_date AND p.effective_end_date
AND a.effective_date BETWEEN r.start_date AND r.end_date
AND a.effective_date BETWEEN en.effective_start_date AND en.effective_end_date
AND a.effective_date BETWEEN e.effective_start_date AND e.effective_end_date
AND a.effective_date BETWEEN pm.effective_start_date AND pm.effective_end_date
AND a.action_type  = 'T'
AND a.id = ra.id
AND a.id = p.id
    
)

GROUP BY e.id, e.emp_number,
TO_CHAR(SYSDATE,'DD/MONTH/YYYY'),
to_char(sysdate,'DD-MM-YYYYY','nls_calendar=''arabic hijrah'''),
ba.acc_number ,
to_char(c.id),
en.name

我的问题是,我真的需要在子查询中应用所有相关条件才能获得与主查询结果相同的有效日期吗? 如果是,它太长了,有没有办法缩短它?提前致谢

【问题讨论】:

  • 您没有在您的选择列表中包括生效日期,那么为什么您删除哪些重复行很重要 - 如果您选择的所有列都相同,为什么不只使用 DISTINCT

标签: sql oracle group-by max aggregate


【解决方案1】:

您可以使用row_number () 过滤重复的行

 WITH cte 
 AS
 (SELECT e.id,
  e.emp_number,
  TO_CHAR(SYSDATE,'DD/MONTH/YYYY') "GREGORIAN",
  to_char(sysdate,'DD-MM-YYYYY','nls_calendar=''arabic hijrah''') HIJRI,
   ba.acc_number "Account Number"
   to_char(c.id) "National ID",
   en.name,

   row_number() over (partition BY e.id,
  e.emp_number,ba.acc_number,c.id,en.name ORDER BY e.id) AS dup_count
     FROM your_query)
     SELECT * FROM cte WHERE dup_count = 1;

【讨论】:

    猜你喜欢
    • 2010-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-06
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2020-09-25
    相关资源
    最近更新 更多