【问题标题】:Insert the table data based on grouping of two columns根据两列分组插入表格数据
【发布时间】:2018-03-26 07:06:22
【问题描述】:

我有一个如下格式的 oracle 表, 例如:

JLID    Dcode   SID     TDT            QTY  
8295783 3119255 9842    3/5/2018        14  
8269771 3119255 9842    3/6/2018        11  
8302211 3119255 1126    3/1/2018        19

这里我对同一个 Dcode 有不同的 SID,现在我需要获取最大数量的 SID。 (即)对于 SID 9842 - (14+11)=25,对于 SID 1126 它是 19,那么结果应该在 SID 9842 上。所以,我们的查询应该返回以下结果

JLID    Dcode   START_DT    END_DT           SID       
111    3119255  3/1/2018    3/31/2018 12:00  9842   

开始日期和结束日期应从 TDT 计算(即开始日期是当月的第一天,结束日期是当月的最后一天) 谁能给我一些建议。

【问题讨论】:

  • 可以带解析函数吗?

标签: sql oracle sql-insert


【解决方案1】:

可能就这么简单:

SELECT Dcode, start_date, end_date, SID FROM (
    SELECT Dcode, SID, TRUNC(start_date, 'MONTH') AS start_date
         , LAST_DAY(end_date) AS end_date
         , ROW_NUMBER() OVER ( PARTITION BY Dcode ORDER BY total_qty DESC ) AS rn
      FROM (
        SELECT Dcode, SID, MIN(TDT) AS start_date, MAX(TDT) AS end_date
             , SUM(QTY) AS total_qty
          FROM mytable
         GROUP BY Dcode, SID
    )
) WHERE rn = 1

在最里面的子查询中,我聚合以获取 DcodeSID 特定值的日期范围和总量。然后我使用分析(窗口)函数来获取总量最大的行。 (如果您想返回多个具有相同数量的 SID 值,则可以使用 RANK() 代替 ROW_NUMBER()。)

【讨论】:

    【解决方案2】:

    这是一个在最终结果中不包含 JLID = 111 的选项,因为我不知道你是从哪里得到的。

    SQL> with test (jlid, dcode, sid, tdt, qty) as
      2        (select 8295783, 3119255, 9842, date '2018-03-05', 14 from dual union
      3         select 8269771, 3119255, 9842, date '2018-08-22', 11 from dual union
      4         select 8302211, 3119255, 1126, date '2018-03-01', 19 from dual union
      5         --
      6         select 1234567, 1112223, 1000, date '2018-06-16', 88 from dual
      7        )
      8    select dcode,
      9           min (trunc (tdt, 'mm')) start_dt,      --> MIN
     10           max (last_day (tdt)) end_dt,           --> MAX
     11           sid
     12      from (select dcode,
     13                   sid,
     14                   tdt,
     15                   sqty,
     16                   rank () over (partition by dcode order by sqty desc) rnk
     17              from (select dcode,
     18                           sid,
     19                           tdt,
     20                           sum (qty) over (partition by dcode, sid) sqty
     21                      from test))
     22     where rnk = 1
     23  group by dcode, sid;                                   --> GROUP BY
    
         DCODE START_DT         END_DT                  SID
    ---------- ---------------- ---------------- ----------
       1112223 01.06.2018 00:00 30.06.2018 00:00       1000
       3119255 01.03.2018 00:00 31.08.2018 00:00       9842
    
    SQL>
    

    【讨论】:

    • 它工作得很好,但有一件事是每当月份发生变化时,它都会给出重复的记录,例如:0000155 01-JAN-13 31-JAN-13 7842 0000155 01-FEB-13 28 -FEB-13 7842 0000155 01-MAR-13 31-MAR-13 7842 0000155 01-APR-13 30-APR-13 7842 0000155 01-MAY-13 31-MAY-13 7842 0000155 01-JUN-13 30-JUN -13 7842 0000155 01-JUL-13 31-JUL-13 7842 0000155 01-AUG-13 31-AUG-13 7842 0000155 01-JUN-14 30-JUN-14 7842 0000155 01-JUL-14 31-JUL-1 7842 0000155 01-AUG-14 31-AUG-14 7842 0000155 01-SEP-14 30-SEP-14 7842,应该是 0000155 01-FEB-13 30-SEP-14 7842
    • 我编辑了我的消息;您应该将 MIN 和 MAX 函数应用于 DATE 值,并且 - 因此 - GROUP BY 其余列。看看吧。
    • 如果您使用的是GROUP BY,我认为您不需要DISTINCT
    • 啊!显然,谢谢你,@David。在复制/粘贴会话期间,我应用了聚合和“忘记”(对,甚至没有注意到)来删除 DISTINCT。
    • 另外 - OP 可能并不完全清楚 - 但您可能希望在最里面的子查询中按 DcodeSID 进行分区。
    猜你喜欢
    • 1970-01-01
    • 2017-05-15
    • 1970-01-01
    • 2013-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    相关资源
    最近更新 更多