我试图将行转换为有限数量的列,同时跳过空白行,并返回非空白行的计数。我能够解决这个限制,所以我更感兴趣的是为什么以下内容作为独立语句工作,但在前面加上
CREATE VIEW TEST AS
? 时失败
with temp (id,line) as (
values (1, 'line a'),
(1, 'line b'),
(1, null),
(1, 'line d'),
(1, 'line e'),
(1, 'line f'),
(2, null),
(2, 'line b'),
(2, 'line c')
),
temp2 as (
select id, line,
row_number() over (partition by id) rn,
sum(1) over (partition by id) rows
from temp
where line is not null
),
temp3 as (
select id,
min(case when rn = 1 then line end) line1,
min(case when rn = 2 then line end) line2,
min(case when rn = 3 then line end) line3,
rows
from temp2
group by id,rows
)
select * from temp3
按原样运行上面的代码给出了我的预期结果:
ID LINE1 LINE2 LINE3 ROWS
1 line a line b line d 5
2 line b line c - 2
但是当前面加上
create view test as
时,会出现以下错误:
SQL State: 42803 Vendor Code: -122 Message: [SQL0122] Column ID or expression in SELECT list not valid. Cause . . . . . : One of the following has occurred: -- The statement contains column name ID and an aggregate function in the SELECT clause and no GROUP BY clause is specified. -- Column name ID is specified in the SELECT clause but not in the GROUP BY clause. -- An expression is specified in the SELECT clause but not in the GROUP BY clause. -- A column or expression that is specified in the ORDER BY clause, but not in the SELECT clause, does not conform to the grouping rules listed above. Recovery . . . : Do one of the following and try the request again: -- If a GROUP BY clause is required, make certain that all columns or expressions in the SELECT list and ORDER BY clause are also in the GROUP BY clause. -- If a GROUP BY clause is not needed, the SELECT list and ORDER BY clause should not contain aggregate functions with column names.
我知道该错误具有误导性,因为如果我从
rows
中删除对 temp3
的引用,它就可以正常运行。因此,这与 OLAP 语句 (sum(1) over (partition by id) rows
) 作为子查询的一部分有关,但我不明白为什么它以一种方式运行正常,而另一种则不然。我无法找到文档为什么不应该按原样运行。
我遇到了同样的问题,并通过与相关表的 FK 进行连接和分组来使其工作。别问我为什么。
我之前已经有过表现得很有趣的复杂查询,并且必须让它与这种黑客一起工作。 顺便说一句,我正在使用 DB2 7.4。
这有效:
CREATE OR REPLACE VIEW V_PERSON_KEY_CHANGE AS
WITH changes AS (
SELECT
personId,
dateColumn,
date_key,
CASE
WHEN key = LAG(dateColumn) OVER (PARTITION BY personId ORDER BY dateColumn)
THEN 0
ELSE 1
END AS changed
FROM person_dates
),
groups AS (
SELECT
personId,
dateColumn,
date_key,
SUM(changed) OVER (PARTITION BY personId ORDER BY dateColumn) AS group_id
FROM changes
)
SELECT
personNames.personId,
personNames.personName,
MIN(dateColumn) as date_from,
MAX(dateColumn) as date_to,
date_key
FROM groups
INNER JOIN personNames ON groups.personId = personNames.personId
GROUP BY
personNames.personId,
personNames.personName,
date_key,
group_id
这不起作用:
CREATE OR REPLACE VIEW V_PERSON_KEY_CHANGE AS
WITH changes AS (
SELECT
personId,
dateColumn,
date_key,
CASE
WHEN key = LAG(dateColumn) OVER (PARTITION BY personId ORDER BY dateColumn)
THEN 0
ELSE 1
END AS changed
FROM person_dates
),
groups AS (
SELECT
personId,
dateColumn,
date_key,
SUM(changed) OVER (PARTITION BY personId ORDER BY dateColumn) AS group_id
FROM changes
)
SELECT
personId,
MIN(dateColumn) as date_from,
MAX(dateColumn) as date_to,
date_key
FROM groups
GROUP BY
personId,
date_key,
group_id