【问题标题】:How to display selected result in one row?如何在一行中显示选定的结果?
【发布时间】:2020-11-25 14:52:42
【问题描述】:

我有这样的表格:

表 1 - 人:

m_id | name  |
-------------
22   | jo    |
-------------
77   | john  |
--------------

表 2 - AMT_DATA

m_id | amt   | activity  |
-------------------------
22   | 100   |    -      |
-------------------------
77   | 300   |    n      |
-------------------------

表 3 - STATUS_DATA:

m_id  |  status     |  s_date         |

 22   |    first    |    01.01.2000 |

 22   |    second   |    01.01.2001 |

 22   |    third    |    01.01.2002 |

 77   |    first    |    01.01.2001 |

 77   |    third    |    01.01.2002 |

对于一个 m_id,表 STATUS_DATA 中可以有更多行。

我有这个选择,但它会为一个 m_id 返回多行。

SELECT PERSON.M_ID, PERSON.NAME, AMT_DATA.AMT, AMT_DATA.ACTIVITY, STATUS_DATA.STATUS, STATUS_DATA.S_DATE FROM PERSON 
INNER JOIN AMT_DATA.M_ID ON AMT_DATA.M_ID = PERSON.M_ID
INNER JOIN STATUS_DATA.M_ID ON STATUS_DATA.M_ID = PERSON.M_ID
WHERE (AMT_DATA.ACTIVITY = '-');

我能否以某种方式获得一行中一个 m_id 的结果?像这样:

person_id  | person_name | amt_data.amt | amt_data.activity | status_data.status1 | status_data.s_date1 | .... |status_data.statusN | status_data.s_dateN

谢谢

【问题讨论】:

  • 您需要对数据进行透视。在 Oracle 数据库的 stackoverflow 中搜索枢轴

标签: sql oracle plsql pivot dynamic-pivot


【解决方案1】:

可以创建一个返回SYS_REFCURSOR类型变量的存储函数,以生成包含条件聚合的sql语句,例如

CREATE OR REPLACE FUNCTION Get_Person_Status RETURN SYS_REFCURSOR IS
  v_recordset SYS_REFCURSOR;
  v_sql       VARCHAR2(32767);
  v_cols      VARCHAR2(32767);  
BEGIN

  SELECT LISTAGG( 'MAX(CASE WHEN rn = '''||rn||''' THEN '||status||' END) AS status'||rn||,
                  'MAX(CASE WHEN rn = '''||rn||''' THEN '||s_date||' END) AS s_date'||rn  ',' )
          WITHIN GROUP ( ORDER BY rn )
    INTO v_cols
    FROM (SELECT ROW_NUMBER() OVER (PARTITION BY m_id ORDER BY s_date) AS rn, s.*
            FROM status_data s);

  v_sql := 'SELECT p.m_id AS person_id,
                   p.name AS person_name,
                   a.amt,
                   a.activity,
                   '|| v_cols ||'
              FROM person p 
              JOIN amt_data a
                ON a.m_id = p.m_id
              JOIN status_data s
                ON s.m_id = p.m_id
             GROUP BY p.m_id, p.name, a.amt, a.activity 
             ORDER BY p.m_id'; 

  OPEN v_recordset FOR v_sql;
  RETURN v_recordset;
END;
/

然后使用调用

VAR rc REFCURSOR
EXEC :rc := Get_Person_Status;
PRINT rc

从 SQL 开发人员的控制台根据 statuss_date 的值动态生成列。

【讨论】:

    猜你喜欢
    • 2013-01-09
    • 2014-03-25
    • 1970-01-01
    • 2013-12-05
    • 1970-01-01
    • 2015-05-04
    • 2021-05-14
    • 1970-01-01
    • 2022-08-12
    相关资源
    最近更新 更多