小组行值进入列,而无需硬编码PL SQL

发布于 2025-01-21 11:02:14 字数 988 浏览 2 评论 0原文

我有一张看起来像这样的桌子:

月份名称
七月的艾莉·
七月七月
·肯·
莱伊·游行·
艾莉·李·克拉姆弗罗伊
弗罗伊·丹妮丝·
阿普尔

我希望它看起来像这样:

73月
·克拉姆·恩·弗罗伊·肯·丹妮丝( AllyLeeKram
donFroyo
KenDenise)

这是我尝试过的解决方案:

SELECT
(SELECT name FROM mytable WHERE month='July') AS July,
(SELECT name FROM mytable WHERE month='March') AS March,
(SELECT name FROM mytable WHERE month='April') AS April
FROM DUAL; 

但是,我不想像month ='七月'那样进行编码的一个月值

吗?

I have a table that looks like this:

MONTHNAME
JulyAlly
JulyDon
JulyKen
MarchLee
MarchFroyo
MarchDenise
AprilKram

I want it to look like this:

JulyMarchApril
AllyLeeKram
DonFroyo
KenDenise

Here is a solution I have tried:

SELECT
(SELECT name FROM mytable WHERE month='July') AS July,
(SELECT name FROM mytable WHERE month='March') AS March,
(SELECT name FROM mytable WHERE month='April') AS April
FROM DUAL; 

However, I do not want to hardcode the month values like month='July'

Is there any way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

‘画卷フ 2025-01-28 11:02:14

似乎您正在尝试通过有条件的汇总来构建查询,并在一年之内按照其顺序排序

SELECT MAX(CASE
             WHEN month = 'March' THEN
              name
           END) AS March,
       MAX(CASE
             WHEN month = 'April' THEN
              name
           END) AS April,
       MAX(CASE
             WHEN month = 'July' THEN
              name
           END) AS July
  FROM (SELECT t.*,
               ROW_NUMBER() OVER(PARTITION BY month ORDER BY name) AS rn
          FROM t) -- "t" represents your mentioned table
 GROUP BY rn
 ORDER BY rn

,并且您可以根据希望使其动态化生成存储的功能代码,例如

CREATE OR REPLACE FUNCTION Get_People_By_Months RETURN SYS_REFCURSOR IS
  v_recordset SYS_REFCURSOR;
  v_sql       VARCHAR2(32767);
  v_cols      VARCHAR2(32767);
BEGIN
  SELECT LISTAGG('MAX(CASE WHEN month = '''||month||''' THEN name END) AS '||month ,',') 
          WITHIN GROUP (ORDER BY month_nr)        
    INTO v_cols
    FROM (SELECT DISTINCT t.month, m.month_nr
            FROM t
            JOIN (SELECT TO_CHAR(TO_DATE(level, 'mm'),
                                 'Month',
                                 'NLS_DATE_LANGUAGE=English') AS month, 
                         level AS month_nr
                    FROM dual
                  CONNECT BY level <= 12) m
              ON t.month = TRIM(m.month));

  v_sql :='SELECT '|| v_cols ||'
             FROM (SELECT t.*, ROW_NUMBER() OVER (PARTITION BY month ORDER BY name) AS rn 
                     FROM t)
            GROUP BY rn 
            ORDER BY rn';


  OPEN v_recordset FOR v_sql;
  DBMS_OUTPUT.PUT_LINE(v_sql);
  RETURN v_recordset;
END;
/

中调用SQL Developer 的控制台

SQL> DECLARE
    result SYS_REFCURSOR;
BEGIN
   :result := Get_People_By_Months;
END;
/

SQL> PRINT result; 

Seems you're trying to construct a query with conditional aggregate, sorting the month-columns in their order within a year such as

SELECT MAX(CASE
             WHEN month = 'March' THEN
              name
           END) AS March,
       MAX(CASE
             WHEN month = 'April' THEN
              name
           END) AS April,
       MAX(CASE
             WHEN month = 'July' THEN
              name
           END) AS July
  FROM (SELECT t.*,
               ROW_NUMBER() OVER(PARTITION BY month ORDER BY name) AS rn
          FROM t) -- "t" represents your mentioned table
 GROUP BY rn
 ORDER BY rn

and you can generate a stored function code as you wish to make it dynamic such as

CREATE OR REPLACE FUNCTION Get_People_By_Months RETURN SYS_REFCURSOR IS
  v_recordset SYS_REFCURSOR;
  v_sql       VARCHAR2(32767);
  v_cols      VARCHAR2(32767);
BEGIN
  SELECT LISTAGG('MAX(CASE WHEN month = '''||month||''' THEN name END) AS '||month ,',') 
          WITHIN GROUP (ORDER BY month_nr)        
    INTO v_cols
    FROM (SELECT DISTINCT t.month, m.month_nr
            FROM t
            JOIN (SELECT TO_CHAR(TO_DATE(level, 'mm'),
                                 'Month',
                                 'NLS_DATE_LANGUAGE=English') AS month, 
                         level AS month_nr
                    FROM dual
                  CONNECT BY level <= 12) m
              ON t.month = TRIM(m.month));

  v_sql :='SELECT '|| v_cols ||'
             FROM (SELECT t.*, ROW_NUMBER() OVER (PARTITION BY month ORDER BY name) AS rn 
                     FROM t)
            GROUP BY rn 
            ORDER BY rn';


  OPEN v_recordset FOR v_sql;
  DBMS_OUTPUT.PUT_LINE(v_sql);
  RETURN v_recordset;
END;
/

then invoke from the SQL Developer's console as

SQL> DECLARE
    result SYS_REFCURSOR;
BEGIN
   :result := Get_People_By_Months;
END;
/

SQL> PRINT result; 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文