java - 如果条件与 SQL 不匹配,则根据列生成更多行

标签 java sql oracle

我有下表,这些表包含有关文件数量和其他一些字段的信息。这是一个查找表或引用表。

我使用的oracle版本是Oracle Database 18c Enterprise E

id             nm    expected_num_files     file_name_expr
1             CVS             3               cvs_d.*.zip
2             CVS             2               cvs_w.*.gz
3             Rite-aid        4               ra_d.*.gz
5             Walgreen        2               wal_d*.txt

我有一个审计表,其中包含收到的信息文件。这两个表都可以在 id 上加入

audit_id    id  file_nm
123          1  cvs_d1.zip
124          1  cvs_d2.zip
125          2  cvs_w1.gz
126          1  cvs_d3.zip

理想情况是所有文件都收到了。

理想的结果 按 id 从 auditlog 组中选择 id , count(*)

   id              count_files 
    1                 3           
    2                 2           
    3                 4           
    5                 2 

审计表的当前结果 但在目前的情况下,我只收到了一些文件

   id              count_files
    1                 3           
    2                 1  

为了达到理想情况,我需要使用空 auditid 从查找表中填充最终表中的虚拟记录

我需要一个像这样的最终输出表。

如果我执行查询select id , count(*) from auditlog group by id
在 final table 上,我会得到上面突出显示的理想结果

audit_id  id  file_nm
    123      1  cvs_d1.zip
    124      1  cvs_d2.zip
    126      1  cvs_d3.zip
    -1       2  cvs_w.*.gz
    125      2  cvs_w1.gz
    -1       3  ra_d*.gz
    -1       3  ra_d.*.gz
    -1       3  ra_d.*.gz
    -1       3  ra_d.*.gz
    -1       5  wal_d*.txt
    -1       5  wal_d*.txt

我们可以很容易地生成 initail 行,但是带有 -1 的行是根据未从列中收到的文件数生成的(他们没有发送的文件数)

解释最终表:因为我们在审计表中有 3 条记录 id 1,所以我们将它们填充到最终表中,但是对于 id 2,我们在审计表中有一个记录,我们填充了它,而对于其他记录,我们填充了 - 1.

最佳答案

至于您提供的数据,您可以按原样保留表格并创建一个 View 以根据需要提供数据:

WITH /* The following is the lookup data you provided: */
     lookup(id, nm, expected_num_files, file_name_expr) AS 
    (SELECT 1, 'CVS',     3,'cvs_d.*.zip' from dual union all
     SELECT 2, 'CVS',     2,'cvs_w.*.gz'  from dual union all
     SELECT 3, 'Rite-aid',4,'ra_d.*.gz'   from dual union all
     SELECT 5, 'Walgreen',2,'wal_d*.txt'  from dual)
   , /* This is the current auditlog as you described: */
     auditlog(audit_id, id, file_nm) AS
    (select 123, 1, 'cvs_d1.zip' from dual union all
     select 124, 1, 'cvs_d2.zip' from dual union all
     select 125, 2, 'cvs_w1.gz'  from dual union all
     select 126, 1, 'cvs_d3.zip' from dual)
   , rn AS (SELECT LEVEL rn FROM dual 
        CONNECT BY LEVEL < (SELECT MAX(expected_num_files) FROM lookup))
/* This is the select you can put into a view: */
SELECT NVL(a.audit_id, -1) AS audit_id
     , NVL(a.id,l.id)      AS id
     , NVL(a.file_nm, l.file_name_expr) AS file_nm
  FROM lookup l
 /* Create a Row for every expected file: */
  JOIN rn r
    ON r.rn <= l.expected_num_files
 FULL JOIN (SELECT a.*
                 , row_number() over(PARTITION BY id ORDER BY audit_id) AS rn 
              FROM auditlog a) a
   ON a.id = l.id
   AND a.rn = r.rn
 ORDER BY 2,1

结果:

AUDIT_ID | ID | FILE_NM
---------+----+-----------
   123   |  1 | cvs_d1.zip
   124   |  1 | cvs_d2.zip
   126   |  1 | cvs_d3.zip
   -1    |  2 | cvs_w.*.gz
   125   |  2 | cvs_w1.gz
   -1    |  3 | ra_d.*.gz
   -1    |  3 | ra_d.*.gz
   -1    |  3 | ra_d.*.gz
   -1    |  3 | ra_d.*.gz
   -1    |  5 | wal_d*.txt
   -1    |  5 | wal_d*.txt

另一种编写查询的方法如下:

WITH lookup(id, nm, expected_num_files, file_name_expr) AS 
    (SELECT 1, 'CVS',     3,'cvs_d.*.zip' from dual union all
     SELECT 2, 'CVS',     2,'cvs_w.*.gz'  from dual union all
     SELECT 3, 'Rite-aid',4,'ra_d.*.gz'   from dual union all
     SELECT 5, 'Walgreen',2,'wal_d*.txt'  from dual)
   , auditlog(audit_id, id, file_nm) AS
    (select 123, 1, 'cvs_d1.zip' from dual union all
     select 124, 1, 'cvs_d2.zip' from dual union all
     select 125, 2, 'cvs_w1.gz'  from dual union all
     select 126, 1, 'cvs_d3.zip' from dual) 
   , rn AS (SELECT LEVEL rn FROM dual 
        CONNECT BY LEVEL < (SELECT MAX(expected_num_files) FROM lookup))
SELECT * FROM auditlog
UNION ALL 
SELECT -1, l.id, l.file_name_expr
  FROM lookup l
  JOIN rn r
    ON r.rn <= l.expected_num_files - NVL((SELECT COUNT(*) FROM auditlog WHERE id = l.id),0)
 ORDER BY 2,1

关于java - 如果条件与 SQL 不匹配,则根据列生成更多行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58031164/

相关文章:

c# - 将一个表的所有行复制到另一个表

sql - postgresql 中的数据透视表

sql - 从子查询中删除 'not in' 子句

oracle - Oracle RAW 列的 Hibernate 映射

python - SqlDeveloper - 在脚本查询中检查没有 IS NULL 子句的 NULL 值

Java 重绘未正确显示组件

java - 如何修复Java中的 'Bound mismatch'

java - 递归 Java 调用中的空结果

java - 看不到椭圆形沿着面板向下移动

具有即插即用数据库的 Java 应用程序