簡體   English   中英

如何在 Oracle 中使用其內容從相關實體的數值聚合的字符串列創建視圖?

[英]How can I create a View in Oracle with a String column whose content is aggregated from numeric values of related entities?

在基於 Oracle SQL 數據庫的 Java 應用程序中,我有以下問題要解決:

一個實體DataDelivery可以由任意數量的Packet組成。 Packet有一個ReportDate和外鍵datadeliveryid

ReportDate的數據類型為 NUMBER(4,0),包含年份 (YYYY),例如 2020 或ReportDate列在表 PACKET 中。

在我看來,我想將DataDelivery顯示為表格行,其中包括一個顯示所有相關數據包的組合報告日期 (YYYY) 的列。 數據包的組合 ReportDate 應該是一個逗號分隔的列表。

重要提示:當“2018”等年份出現多次時,不得重復。

因此,具有 3 個數據包的 DataDelivery 如下所示:

DataDelivery
    PACKET1, ReportDate:2020
    PACKET2, ReportDate:2020
    PACKET3, ReportDate:2018
    PACKET4, ReportDate: `null`

shall be displayed as:    2018, 2020

也就是說, null必須忽略,2020 不能重復。 並且值必須升序排序。

如果所有數據包的 ReportDate 為 null 值,則視圖中的值必須為空。


為簡單起見,我省略了我的問題的一些復雜性,包括幾個連接等。此外,日期只能是20182020null ,盡管刪除這個約束會更好。 也許有人可以根據我在這里的嘗試提出解決方案:

            CASE
                WHEN COUNT(CASE eqpaket.berichtszeitraum WHEN 2020 THEN 2020 END) = COUNT(*) THEN '2020'
                WHEN COUNT(CASE eqpaket.berichtszeitraum WHEN 2018 THEN 2018 END) = COUNT(*) THEN '2018'
                WHEN COUNT(distinct eqpaket.berichtszeitraum) > 1 THEN
                    listagg(eqpaket.berichtszeitraum, ',') within group(order by datenlieferungid)
                ELSE ''
            END AS berichtszeitraum,

當所有 ReportDates 都相同時,這很有效。 當它們不同時,我會得到重復。 在上面的示例中,我會得到: 2018, 2020, 2020 需要刪除那些重復項,如果我堅持這種方法,這必須在 CASE -- END 內發生。

對於 Oracle 11g 及更高版本,您可以使用 listagg

select listagg(distinct ReportDate, ',') within group (order by ReportDate)
from DataDelivery

分兩步進行(因為您的數據庫版本不支持listaggdistinct ):

SQL> with datedelivery (datedeliveryid, packet, reportdate) as
  2    -- sample data
  3    (select 1, 'packet1', 2020 from dual union all
  4     select 1, 'packet2', 2020 from dual union all
  5     select 1, 'packet3', 2018 from dual union all
  6     select 1, 'packet4', null from dual union all
  7     --
  8     select 2, 'packet5', 2017 from dual union all
  9     select 2, 'packet6', 2017 from dual union all
 10     select 2, 'packet7', null from dual
 11    )
 12  -- query you need
 13  select datedeliveryid,
 14         listagg(reportdate, ', ') within group (order by reportdate) years
 15  from (-- first find DISTINCT values, then aggregate them
 16        select distinct datedeliveryid, reportdate
 17        from datedelivery
 18       )
 19  group by datedeliveryid;

DATEDELIVERYID YEARS
-------------- --------------------
             1 2018, 2020
             2 2017

SQL>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM