Oracle SQL:SELECT 语句中的内联表?
Posted
技术标签:
【中文标题】Oracle SQL:SELECT 语句中的内联表?【英文标题】:Oracle SQL: inline table within a SELECT statement? 【发布时间】:2020-01-14 09:49:08 【问题描述】:我正在配置一个将数据从系统 A 移动到系统 B 的集成工具。我提供了一个 SQL SELECT 语句,它针对系统 A 运行,该语句的输出决定了系统 B 中的更新内容。例如,要更新 Team 1 的国际销售数据:
SELECT
'Team1_Int_Sales_Count' Code,
count(*) Count,
to_char(<integration tool date syntax>) Period
FROM
Sales
JOIN
ADozenMoreTables ON stuff
WHERE
ADozenOpaqueFields IN ADozenOpaqueReferences
AND Sales.Date BETWEEN <integration tool date syntax>
AND Team = 'Team1'
AND Sales.Type = 'International'
它使用返回的字段Code
、Value
和Period
使用该值更新该期间的代码。 (字段由它们所在的顺序标识,而不是按名称。)
然后,对于Team 1的国内销售,我复制并粘贴了整个查询,并更改了代码和一个WHERE
子句:
SELECT
'Team1_Dom_Sales_Count' Code,
<otherwise as above>
AND Sales.Type = 'Domestic'
然后我为第 2 组和第 3 组再复制粘贴四次
SELECT
'Team2_Int_Sales_Count' Code,
<snip>
AND Team = 'Team2'
AND Sales.Type = 'International'
SELECT
'Team2_Dom_Sales_Count' Code,
<snip>
AND Team = 'Team2'
AND Sales.Type = 'Domestic'
SELECT
'Team3_Int_Sales_Count' Code,
<snip>
AND Team = 'Team3'
AND Sales.Type = 'International'
SELECT
'Team3_Dom_Sales_Count' Code,
<snip>
AND Team = 'Team3'
AND Sales.Type = 'Domestic'
完整的问题有一个 ~60 行的 SELECT
语句,具有 3x3x3 排列,所涉及的复制/粘贴量让我感到恐惧。
有没有什么方法可以编写一条 SQL SELECT
语句,该语句将逐步遍历所有排列而无需复制粘贴重复?在我看来,我会在一个临时表中内联创建排列,或者作为一个二维数组,查询可以返回代码和其他两个字段匹配的值:
'Team1_Int_Sales_Count', 'Team1', 'International',
'Team1_Dom_Sales_Count', 'Team1', 'Domestic',
'Team2_Int_Sales_Count', 'Team2', 'International',
'Team2_Dom_Sales_Count', 'Team2', 'Domestic',
'Team3_Int_Sales_Count', 'Team3', 'International',
'Team3_Dom_Sales_Count', 'Team3', 'Domestic' Permutations
这里的约束是集成工具要求我为每个任务提供一个 SELECT
语句。我不能在它前面加上WITH
语句,或者声明函数,或者将复杂的查询作为视图存储在源数据库中,或者做任何有趣或好的事情。它是一个 Oracle ODBC 连接,所以它使用 Oracle SQL。
【问题讨论】:
【参考方案1】:你似乎想要一个交叉连接。
SELECT t.team || ct.code code,
t.team,
ct.type
FROM (SELECT '_Int_Sales_Count' code,
'International' type
FROM dual
UNION ALL
SELECT '_Dom_Sales_Count' code,
'Domestic' type
FROM dual) ct
CROSS JOIN (SELECT 'Team1' team
FROM dual
UNION ALL
SELECT 'Team2' team
FROM dual
UNION ALL
SELECT 'Team3' team
FROM dual) t;
db<>fiddle
【讨论】:
【参考方案2】:排列表可以这样构造:
SELECT
Permutations.Code AS Code,
COUNT(*) AS Count,
...
JOIN (SELECT * FROM (
(SELECT 'Team1_Int_Sales_Count' AS Code, 'Team1' AS Team, 'International' AS Type FROM Dual),
UNION (SELECT 'Team1_Dom_Sales_Count' AS Code, 'Team1' AS Team, 'Domestic' AS Type FROM Dual),
UNION (SELECT 'Team2_Int_Sales_Count' AS Code, 'Team2' AS Team, 'International' AS Type FROM Dual),
UNION (SELECT 'Team2_Dom_Sales_Count' AS Code, 'Team2' AS Team, 'Domestic' AS Type FROM Dual),
UNION (SELECT 'Team3_Int_Sales_Count' AS Code, 'Team3' AS Team, 'International' AS Type FROM Dual),
UNION (SELECT 'Team3_Dom_Sales_Count' AS Code, 'Team3' AS Team, 'Domestic' AS Type FROM Dual)
)) AS Permutations
ON Permutations.Team = Sales.Team AND Permutations.Type = Sales.Type
WHERE...
【讨论】:
【参考方案3】:我会这样做:
with
team as (select level lv from dual connect by level <= 3)
, bas as (select '_Int_Sales_Count' n_count, 'International' type from dual
union all select '_Dom_Sales_Count' n_count, 'Domestic' type from dual)
, permutations as
( select 'Team' || lv ||n_count as code, 'Team' || lv as team, type from team join bas on (1=1))
select * from permutations
但有限制:
select 'Team' || lv ||n_count as code, 'Team' || lv as team, type from
(select level lv from dual connect by level <= 3) team,
(select '_Int_Sales_Count' n_count, 'International' type from dual
union all select '_Dom_Sales_Count' n_count, 'Domestic' type from dual) bas
【讨论】:
谢谢,但是这个集成工具的限制是第一个关键字必须是SELECT
。也许我应该在问题中更清楚地说明这一点。以上是关于Oracle SQL:SELECT 语句中的内联表?的主要内容,如果未能解决你的问题,请参考以下文章
sql的嵌套查询,把一次查询的结果做为表继续进一步查询;内联视图
如何写sql语句去掉oracle返回结果中的空值(NULL)
oracle语句,我想查询A表中的a字段下的值不等于B表中b的值的数据,