如何在 SQL 中将标量子查询转换为条件 OLAP 函数?
How to translate a scalar subquery into a conditional OLAP function in SQL?
我正在使用 Teradata 15.10。我有一个包含两列 last_name 和 first_name 的 table。对于每一行,我需要计算有多少其他行具有相同的 last_name 和 first_name,但值相反,并显示该计数(即使它等于 0)。目前,我正在使用这个查询:
SELECT LAST_NAME,
FIRST_NAME,
(SELECT Count(*)
FROM myTable AS T1
WHERE T1.FIRST_NAME = T2.LAST_NAME
AND T1.LAST_NAME = T2.FIRST_NAME) AS REVERSE_NAME_COUNT
FROM myTable AS T2
不幸的是,这不是很快,我还有很多其他专栏在做这种计数。我想知道是否有一种方法可以将上面的标量子查询转换为这样的 OLAP 函数:
SUM(CASE WHEN T1.FIRST_NAME = T2.LAST_NAME AND T1.LAST_NAME = T2.FIRST_NAME THEN 1 ELSE 0 END) OVER(ROWS UNBOUNDED PRECEDING)
但据我了解,无法访问分区中当前正在处理的值。有没有其他方法可以编写我的子查询?
输入示例:
FIRST_NAME LAST_NAME
----------------------------------
SYLVIE BOUVET
LUCIENNE BRUN
BOUVET SYLVIE
FRANCINE CARON
BRUN LUCIENNE
BRUN LUCIENNE
KEVIN MACHETEL
REMI MINVIELLE
QUENTIN THUILLIER
MINVIELLE REMI
期望的输出示例:
FIRST_NAME LAST_NAME REVERSE_NAME_COUNT
------------------------------------------------------
SYLVIE BOUVET 1
LUCIENNE BRUN 2
BOUVET SYLVIE 1
FRANCINE CARON 0
BRUN LUCIENNE 1
BRUN LUCIENNE 1
KEVIN MACHETEL 0
REMI MINVIELLE 1
QUENTIN THUILLIER 0
MINVIELLE REMI 1
您是在谈论 标量子查询 在 Select 中吗?
SELECT
last_name
,(
SELECT Count(*)
FROM myTable AS T1
WHERE T1.FIRST_NAME = T2.LAST_NAME
)
FROM myTable AS t2
那么你是对的,你不能把它重写成一个OLAP函数。
那些标量子查询往往性能不佳,但您通常可以使用外部连接重写它们:
SELECT
t2.last_name
,t1.Cnt
FROM myTable AS t2
LEFT JOIN
(
SELECT first_name, Count(*) AS Cnt
FROM myTable
GROUP BY 1
) AS t1
ON T1.FIRST_NAME = T2.LAST_NAME
感谢@dnoeth,我找到了解决方案。
SELECT
T2.first_name
T2.last_name
,SUM(t1.Cnt)
FROM myTable AS T2
LEFT JOIN
(
SELECT first_name, last_name, Count(*) AS Cnt
FROM myTable
GROUP BY 1, 2
) AS T1
ON T1.first_name = T2.last_name
AND T1.last_name = T2.first_name
GROUP BY 1, 2
我正在使用 Teradata 15.10。我有一个包含两列 last_name 和 first_name 的 table。对于每一行,我需要计算有多少其他行具有相同的 last_name 和 first_name,但值相反,并显示该计数(即使它等于 0)。目前,我正在使用这个查询:
SELECT LAST_NAME,
FIRST_NAME,
(SELECT Count(*)
FROM myTable AS T1
WHERE T1.FIRST_NAME = T2.LAST_NAME
AND T1.LAST_NAME = T2.FIRST_NAME) AS REVERSE_NAME_COUNT
FROM myTable AS T2
不幸的是,这不是很快,我还有很多其他专栏在做这种计数。我想知道是否有一种方法可以将上面的标量子查询转换为这样的 OLAP 函数:
SUM(CASE WHEN T1.FIRST_NAME = T2.LAST_NAME AND T1.LAST_NAME = T2.FIRST_NAME THEN 1 ELSE 0 END) OVER(ROWS UNBOUNDED PRECEDING)
但据我了解,无法访问分区中当前正在处理的值。有没有其他方法可以编写我的子查询?
输入示例:
FIRST_NAME LAST_NAME
----------------------------------
SYLVIE BOUVET
LUCIENNE BRUN
BOUVET SYLVIE
FRANCINE CARON
BRUN LUCIENNE
BRUN LUCIENNE
KEVIN MACHETEL
REMI MINVIELLE
QUENTIN THUILLIER
MINVIELLE REMI
期望的输出示例:
FIRST_NAME LAST_NAME REVERSE_NAME_COUNT
------------------------------------------------------
SYLVIE BOUVET 1
LUCIENNE BRUN 2
BOUVET SYLVIE 1
FRANCINE CARON 0
BRUN LUCIENNE 1
BRUN LUCIENNE 1
KEVIN MACHETEL 0
REMI MINVIELLE 1
QUENTIN THUILLIER 0
MINVIELLE REMI 1
您是在谈论 标量子查询 在 Select 中吗?
SELECT
last_name
,(
SELECT Count(*)
FROM myTable AS T1
WHERE T1.FIRST_NAME = T2.LAST_NAME
)
FROM myTable AS t2
那么你是对的,你不能把它重写成一个OLAP函数。
那些标量子查询往往性能不佳,但您通常可以使用外部连接重写它们:
SELECT
t2.last_name
,t1.Cnt
FROM myTable AS t2
LEFT JOIN
(
SELECT first_name, Count(*) AS Cnt
FROM myTable
GROUP BY 1
) AS t1
ON T1.FIRST_NAME = T2.LAST_NAME
感谢@dnoeth,我找到了解决方案。
SELECT
T2.first_name
T2.last_name
,SUM(t1.Cnt)
FROM myTable AS T2
LEFT JOIN
(
SELECT first_name, last_name, Count(*) AS Cnt
FROM myTable
GROUP BY 1, 2
) AS T1
ON T1.first_name = T2.last_name
AND T1.last_name = T2.first_name
GROUP BY 1, 2