Is there a generic workaround to express a derived column list in Oracle (and MySQL)?

后端 未结 3 1405
时光说笑
时光说笑 2021-02-19 00:20

Many SQL databases support what the SQL standard calls a . Such databases include at least CUBRID, Derby, Firebird, HSQLDB, Postgres, SQL

相关标签:
3条回答
  • 2021-02-19 00:42

    As suggested by user tbone here, common table expressions are a good solution to my problem, at least for Oracle. For completeness, here is my example query written using CTEs in Oracle

    -- Rename a <derived table> to u(b) with Oracle
    with u(b) as (select 1 from dual) 
    select u.b from u
    
    -- Rename a <derived table> to u(b) with H2, which only knows recursive CTEs
    -- Thanks to a comment by user a_horse_with_no_name
    with recursive u(b) as (
      select 1
      union all
      select null where false
    )
    select u.b from u
    
    0 讨论(0)
  • 2021-02-19 00:48

    For a MySQL solution, you could use a UNION to set the names of all the columns in a zero-row query term, and then subsequently query something more complex:

    SELECT null AS a, null AS b, null AS c FROM dual WHERE false
    UNION ALL
    SELECT <expr>, <expr>, <expr>
    FROM <realtable>...
    

    Only the first query term of a UNION defines the column names of the whole query. Column names (or lack thereof) in subsequent query terms don't affect the ultimate column names.

    You do need to know the number of columns, but it should be pretty easy to keep the two query terms separate. As far as I know, it works in both Oracle and MySQL (however, I have only tested it in MySQL, not in Oracle).

    0 讨论(0)
  • 2021-02-19 00:56

    Since you MUST know the number of columns, but not necessarily the column names, you can use the WITH clause to rename these columns as you wish. For example (WITH works in Oracle and SQL Server, don't have MySQL instance handy):

    WITH t(x,y,z) as (select * from TABLE(fn_returning_xcols(3)))
    select * from t;
    

    Here we don't know the column names in the inner select, but we can rename them in outer WITH clause.

    Another example using a PIVOT in Oracle:

    WITH t(a,b,c,d,e) as 
    (
     select * from 
     (
      select level as levl from dual connect by level <= 5
     )
     PIVOT(max(levl) as l for levl in (1,2,3,4,5))
    )
    select * from t;
    

    Again, we don't care what the inner select column names are (the inner pivot creates somewhat odd column names), we just need to know how many columns and we can rename.

    0 讨论(0)
提交回复
热议问题