过滤对 crosstab() 查询结果的意外影响
Posted
技术标签:
【中文标题】过滤对 crosstab() 查询结果的意外影响【英文标题】:Unexpected effect of filtering on result from crosstab() query 【发布时间】:2019-07-25 19:40:48 【问题描述】:我有一个crosstab()
查询,如下所示:
SELECT *
FROM crosstab(
'SELECT row_name, extra1, extra2..., another_table.category, value
FROM table t
JOIN another_table ON t.field_id = another_table.field_id
WHERE t.field = certain_value AND t.extra1 = val1
ORDER BY row_name ASC',
'SELECT category_name FROM category_name WHERE field = certain_value'
) AS ct(row_name text, extra1 text, extra2 text, ...)
简化示例,实际查询非常复杂且包含重要信息。上面的查询在使用table.extra1 = val1
过滤后返回N 个结果行。
当我按如下方式更改查询时:
SELECT *
FROM crosstab(
'SELECT row_name, extra1, extra2..., another_table.category, value
FROM table t
JOIN another_table ON t.field_id = another_table.field_id
WHERE t.field = certain_value AND t.extra1 IN (val1, ...) --> more values
ORDER BY row_name ASC',
'SELECT category_name FROM category_name WHERE field = certain_value'
) AS ct(row_name text, extra1 text, extra2 text, ...)
WHERE extra1 = val1; --> condition on the result
添加了更多可能的值table.extra1 IN (val1, ...)
和最终条件WHERE extra1 = val1
。现在我得到 less 行比原来的行。更糟糕的是,如果我向IN (val1, ...)
添加更多值,我会得到更少 行。这是为什么呢?
【问题讨论】:
【参考方案1】:extra1, extra2, ...
是交叉表术语中的“额外列”。The manual for the tablefunc module 解释规则:
它也可能有一个或多个“额外”列。
row_name
列必须 成为第一。类别和value
列必须是最后两列, 以该顺序。处理row_name
和category
之间的任何列 作为“额外”。 对于具有相同row_name
值的所有行,“额外”列应相同。
再往下:
输出
row_name
列以及任何“额外”列从组的第一行复制。
我对关键部分的大胆强调。
你只能按row_name
排序:
ORDER BY row_name ASC
在您过滤的第一个示例中无关紧要:
WHERE ... t.extra1 = 'val1' -- single quotes by me
无论如何,所有输入行都有extra1 = 'val1'
。但在第二个示例中,您使用以下过滤器很重要:
WHERE ... t.extra1 IN('val1', ...) --> More values
现在,额外列extra1
违反了上述第一个粗体要求。虽然第一个输入查询的排序顺序是不确定的,但“额外”列extra1
的结果值是任意选取的。 extra1
的可能值越多,最终具有“val1”的行就越少:这就是您观察到的。
您仍然可以使其工作:为每个至少具有其中一个的 row_name
报告 extra1 = 'val1'
,请将 ORDER BY
更改为:
ORDER BY row_name, (extra1 <> 'val1')
将“val1”排在最前面。 boolean
表达式的解释(带有更多链接):
其他“额外”列仍然是任意选择的,而排序顺序不确定。
交叉表基础知识:
PostgreSQL Crosstab Query Postgresql crosstab query with multiple "row name" columns【讨论】:
我仍然有多个值的一些问题。例如,如果我用val2
过滤extra1
,我会得到100 个结果。但是,如果我使用...t.extra1 IN('val1', 'val2')
和...(extra1 <> 'val1'), (extra1 <> 'val2')
,对于那些在80
附近有extra1 和'val2' 的人,我会得到不同的结果大小。
在这种情况下,您可以ORDER BY row_name, (extra1 <> 'val2')
在任何可用的地方获取“val2”。 (从列表中删除 (extra1 <> 'val1')
。)
问题是extra1
可以从允许值列表['value1', 'value2', 'value3'...'valueN']
中获得一个值。正常情况是允许过滤多个值['value1', 'value2']
而不仅仅是一个。是否仍然可以使用<>
运算符来实现它?
请提出一个包含所有必要细节的新问题。评论不是地方...(您可以随时链接到这个以获得上下文,并在此处的 cmets 中放回链接以引起我的注意。)
你是对的:)。这里出现了一个新问题***.com/questions/57221777/…以上是关于过滤对 crosstab() 查询结果的意外影响的主要内容,如果未能解决你的问题,请参考以下文章
MS Access CrossTab 查询 - 跨 3 个表