获取多个行值作为列值

时间:2017-06-16 06:55:06

标签: sql oracle

我有两个表MASTER_TABLEDOCUMENTS表。两者都与列 reference_id 相关。 DOCUMENTS表包含 doc_id doc_type doc_creation_date 列 对于每个 DOCUMENTS ,我们可以在doc_type表格中为多个 doc_creation_date 添加多个条目。我的目标是在一行中为每个 doc_type 获取 doc_id doc_type 最大 doc_creation_date

MASTER_TABLE

REFERENCE_ID    COLUMN1 COLUMN2
     1            DATA1  DATA2
     2            DATA3  DATA4
     3            DATA5  DATA6



DOCUMENTS

REFERENCE_ID    DOC_ID  DOC_TYPE    DOC_CREATION_DATE
     1            11      PDF           16/06/2017
     1            12      XLS           16/06/2017
     1            13      TXT           16/06/2017
     1            14      PDF           15/06/2017
     1            15      XLS           15/06/2017
     1            16      TXT           15/06/2017
     2            17      PDF           16/06/2017
     2            18      XLS           16/06/2017
     2            19      TXT           16/06/2017




EXPECTED OUTPUT

REFERENCE_ID    DOC_ID_PDF  DOC_ID_XLS  DOC_ID_TXT
     1             11           12          13
     2             17           18          19

这是否可以使用单个查询来实现。我尝试了自我加入和转动,但我猜错了方法。我们可以使用Oracle 11g和12c数据库。

1 个答案:

答案 0 :(得分:1)

Rank() Over([Partition by] Order by)后跟Pivot将解决您的问题。 以下是代码。如果多个doc_ids具有相同的最大创建日期,以下内容将为您提供max doc_id。如果您需要上述方案的最小doc_id,请在max子句中将min函数更改为pivot

WITH master_table AS
     (SELECT 1 reference_id, 'DATA1' column1, 'DATA2' column2
        FROM DUAL
      UNION
      SELECT 2 reference_id, 'DATA3' column1, 'DATA4' column2
        FROM DUAL
      UNION
      SELECT 3 reference_id, 'DATA5' column1, 'DATA6' column2
        FROM DUAL),
     documents AS
     (SELECT 1 reference_id, 11 doc_id, 'PDF' doc_type,
             '16/06/2017' doc_creation_date
        FROM DUAL
      UNION
      SELECT 1 reference_id, 12 doc_id, 'XLS' doc_type,
             '16/06/2017' doc_creation_date
        FROM DUAL
      UNION
      SELECT 1 reference_id, 13 doc_id, 'TXT' doc_type,
             '16/06/2017' doc_creation_date
        FROM DUAL
      UNION
      SELECT 1 reference_id, 14 doc_id, 'PDF' doc_type,
             '15/06/2017' doc_creation_date
        FROM DUAL
      UNION
      SELECT 1 reference_id, 15 doc_id, 'XLS' doc_type,
             '15/06/2017' doc_creation_date
        FROM DUAL
      UNION
      SELECT 1 reference_id, 16 doc_id, 'TXT' doc_type,
             '15/06/2017' doc_creation_date
        FROM DUAL
      UNION
      SELECT 2 reference_id, 17 doc_id, 'PDF' doc_type,
             '16/06/2017' doc_creation_date
        FROM DUAL
      UNION
      SELECT 2 reference_id, 18 doc_id, 'XLS' doc_type,
             '16/06/2017' doc_creation_date
        FROM DUAL
      UNION
      SELECT 2 reference_id, 19 doc_id, 'TXT' doc_type,
             '16/06/2017' doc_creation_date
        FROM DUAL)
SELECT *
  FROM (SELECT reference_id, doc_id, doc_type
          FROM (SELECT x.reference_id, y.doc_id, y.doc_type,
                       y.doc_creation_date,
                       RANK () OVER (PARTITION BY x.reference_id, y.doc_type ORDER BY y.doc_creation_date DESC)
                                                                         RANK
                  FROM master_table x JOIN documents y
                       ON (x.reference_id = y.reference_id)
                       )
         WHERE RANK = 1)
  pivot (max(doc_id)
  FOR doc_type
  IN ( 'PDF' doc_id_pdf, 'XLS'  doc_id_xls,'TXT'  doc_id_txt));