Oracle SQL显示一年中的所有月份,包含或不包含值ORA-01841

n53p2ov0  于 2022-11-03  发布在  Oracle
关注(0)|答案(1)|浏览(212)

我有一个问题,我绝望,我有数据分布在几天,并希望显示这一整年的月份和一次在几周内。
我的问题与月份,我得到的选择我的数据显示(一月,九月),但我希望所有的月份为选定的一年显示,即使他们是空的。为此,我已经使自己一个“与”(复制),现在试图加入这个,但得到一个ORA-01841错误。
以及如何实现整个构造以仅显示周。

WITH MONAT_ZAEHLER (MZ) AS 
( 
SELECT 
   TO_CHAR(ADD_MONTHS(TO_DATE('01.2022','MM.YYYY'),LEVEL -1),'Month', 'NLS_DATE_LANGUAGE = GERMAN') AS  GRD_ROW_ID
  FROM
  DUAL
  CONNECT BY LEVEL <= 12
)

SELECT 
  TO_CHAR(GEN_DATUM,'Month', 'NLS_DATE_LANGUAGE = GERMAN') AS  GRD_ROW_ID

, COUNT( DISTINCT CASE
    WHEN LP_BELEGUNG.ART = 1 THEN  LP_BELEGUNG.LP_BELEGUNG_ID
    ELSE NULL
  END ) AS "1"

, COUNT( DISTINCT CASE
    WHEN LP_BELEGUNG.ART = 2 THEN  LP_BELEGUNG.LP_BELEGUNG_ID
    ELSE NULL
  END ) AS "2"

, COUNT( DISTINCT CASE
    WHEN LP_BELEGUNG.ART = 3 THEN  LP_BELEGUNG.LP_BELEGUNG_ID
    ELSE NULL
  END ) AS "3"

, COUNT( DISTINCT CASE
    WHEN LP_BELEGUNG.ART = 99 THEN  LP_BELEGUNG.LP_BELEGUNG_ID
    ELSE NULL
  END ) AS "99"
FROM
  LP_BELEGUNG

FULL OUTER JOIN MONAT_ZAEHLER ON  TRUNC(LP_BELEGUNG.GEN_DATUM, 'Month') = MONAT_ZAEHLER.MZ

WHERE 
  TO_CHAR(GEN_DATUM, 'YYYY') = '2022'

GROUP BY
  TO_CHAR(GEN_DATUM,'Month', 'NLS_DATE_LANGUAGE = GERMAN')
whhtz7ly

whhtz7ly1#

出现错误是因为您将月份转换为CTE中的名称字符串,然后尝试再次将其转换为GRD_ROW_ID别名。
解决方案基本上与前面的问题相同,但是现在您希望CTE每月有一行-您正在这样做,但是您应该在CTE中将其保留为日期类型,而不是在此处将其转换为字符串:

with cte (dt) as (
  select add_months(date '2022-01-01', level - 1)
  from dual
  connect by level <= 12
)

...然后将 * 该 * 实际日期值转换为字符串:

SELECT
  TO_CHAR(cte.dt, 'Month', 'NLS_DATE_LANGUAGE = GERMAN') AS GRD_ROW_ID
...

...和以前一样,使用日期范围对实际表进行外部联接:

FROM
  cte
LEFT JOIN
  LP_BELEGUNG 
ON
  LP_BELEGUNG.GEN_DATUM >= cte.dt AND LP_BELEGUNG.GEN_DATUM < add_months(cte.dt, 1)
GROUP BY
  cte.dt
ORDER BY
  cte.dt

......这次查找GEN_DATUM大于或等于cte.dt值的值(再次,如前所述),cte.dt值是该月第一天的第一天午夜;并且小于add_months(cte.dt, 1),即下一个月第一天的第一天的午夜,所以对于一月份,这将是〉= 2022-01-01 00:00:00并且〈2022-02-01 00:00:00,这是该月份中所有可能的日期和时间。
| GRD_ROW_标识|样本集_1|第2次试验|安扎列_ART_3|第4部分|
| - -|- -|- -|- -|- -|
| 亚努阿尔|第0页|第0页|第0页|第0页|
| 二月|第0页|第0页|第0页|第0页|
| 麦尔兹|第0页|第0页|第0页|第0页|
| 四月|第0页|第0页|第0页|第0页|
| 迈|第0页|第0页|第0页|第0页|
| 朱尼|第0页|第0页|第0页|第0页|
| 尤利|第0页|第0页|第0页|第0页|
| 八月|第0页|第0页|第0页|第0页|
| 九月|一个|一个|一个|七个|
| 十月|第0页|第0页|第0页|第0页|
| 十一月|第0页|第0页|第0页|第0页|
| 十二月|第0页|第0页|第0页|第0页|
fiddle
要获得一年中每周的行,您可以再次执行类似的操作,但以7天为一个块:

with cte (dt) as (
  select date '2022-01-01' + 7 * (level - 1)
  from dual
  connect by level <= 53
)
SELECT
  TO_CHAR(cte.dt, 'YYYY-WW') AS GRD_ROW_ID
...
FROM
  cte
LEFT JOIN
  LP_BELEGUNG 
ON
  LP_BELEGUNG.GEN_DATUM >= cte.dt AND LP_BELEGUNG.GEN_DATUM < cte.dt + 7
  AND LP_BELEGUNG.GEN_DATUM < add_months(trunc(cte.dt, 'YYYY'), 12)
GROUP BY
  cte.dt
ORDER BY
  cte.dt

它在连接中有一个额外的检查,以阻止它包括第53周的数据,这实际上是在下一年-我猜你会想这样做。
fiddle

相关问题