programing

Oracle(및 MySQL)에서 파생 열 목록을 표현하기 위한 일반적인 해결 방법이 있습니까?

linuxpc 2023. 7. 15. 09:45
반응형

Oracle(및 MySQL)에서 파생 열 목록을 표현하기 위한 일반적인 해결 방법이 있습니까?

많은 SQL 데이터베이스는 SQL 표준이 말하는 것을 지원합니다.<derived column list>이러한 데이터베이스에는 CUBRID, Derby, Firebird, HSQLDB, Postgres, SQL Server 및 Sybase SQL Anywhere 이상이 포함됩니다.SQL:2008 사양의 (간체) 발췌본

7.6 <table reference>

Format
<table reference> ::=
    <table or query name> [ [ AS ] <correlation name>
      [ <left paren> <derived column list> <right paren> ] ]
  | <derived table> [ AS ] <correlation name>
      [ <left paren> <derived column list> <right paren> ]

즉, 저는 다음과 같은 것을 표현할 수 있습니다(예: 상당히 표준에 부합하는 Postgres).

-- Rename a <table or query name> to u(b)
with t(a) as (select 1)
select * from t as u(b)

-- Rename a <derived table> to u(b)
select * from (select 1) as u(b)

Oracle 설명서에 따르면 다음을 사용하여 열 이름을 변경할 수 없습니다.<derived column list>사양.물론 테이블과 열의 이름을 다음과 같이 개별적으로 바꿀 수 있습니다.

-- Rename a <table or query name> to u(b)
with t(a) as (select 1 from dual)
select u.a b from t u;

-- Rename a <derived table> to u(b)
select u.a b from (select 1 a from dual) u;

그러나 이를 위해서는 이전 구문보다 파생된 테이블(실제 열 이름)에 대한 지식이 더 필요합니다.또한 이름이 바뀐 열은 투영 후에만 사용할 수 있습니다(예:ORDER BY절), 투영 자체를 포함하여 다른 절에는 없습니다.

Oracle(및 MySQL)에서 SQL 표준이 제안하는 방식으로 테이블과 열의 이름을 바꾸는 더 일반적인 방법이 있습니까?특히 배열 중첩, 피벗/피벗 테이블 이름 바꾸기, 복잡한 하위 쿼리 인라인, 테이블 함수의 결과 이름 바꾸기 등에 유용할 수 있습니다.

N.B: 위의 예들에 너무 집중하지 마세요.그들은 단지 문제를 설명하기 위해 여기에 왔습니다.실제 쿼리는 훨씬 복잡하기 때문에 이름 바꾸기를 구현하는 매우 일반적인 방법을 찾고 있습니다.u(b)

참고: MySQL과 같은 데이터베이스에서 작동하는 솔루션을 찾고 있습니다.관련 질문:
하위 선택에서 별칭이 없는 숫자 리터럴을 선택하는 방법

MySQL 솔루션의 경우 다음을 사용할 수 있습니다.UNION0행 쿼리 용어에 있는 모든 열의 이름을 설정한 다음 더 복잡한 것을 쿼리합니다.

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

UNION의 첫 번째 쿼리 용어만 전체 쿼리의 열 이름을 정의합니다.후속 쿼리 용어의 열 이름(또는 열 이름 없음)은 최종 열 이름에 영향을 주지 않습니다.

를 알아야 하지만 두 개의 쿼리 항을 구분하는 것은 매우 쉽습니다.제가 알기로는 Oracle과 MySQL 모두에서 작동하는 것으로 알고 있습니다(단, 저는 Oracle이 아닌 MySQL에서만 테스트했습니다).

열 수는 알고 있어야 하지만 열 이름은 알고 있어야 하므로 WITH 절을 사용하여 원하는 대로 열 이름을 바꿀 수 있습니다.예: (WITH는 Oracle 및 SQL Server에서 작동하며 MySQL 인스턴스를 사용할 수 없습니다.)

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

여기서는 내부 선택에서 열 이름을 알 수 없지만 외부 WITH 절에서 이름을 바꿀 수 있습니다.

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;

다시 말씀드리지만, 내부 선택 열 이름이 무엇이든 상관없습니다(내부 피벗은 다소 이상한 열 이름을 생성합니다). 열 수를 알고 이름을 바꿀 수 있으면 됩니다.

여기서 사용자 tbone이 제안한 바와 같이, 일반적인 테이블 표현식은 적어도 Oracle의 경우에는 제 문제에 대한 좋은 해결책입니다.완전성을 위해 Oracle에서 CTE를 사용하여 작성한 쿼리 예제입니다.

-- 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

언급URL : https://stackoverflow.com/questions/14127707/is-there-a-generic-workaround-to-express-a-derived-column-list-in-oracle-and-my

반응형