我有一个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
。现在我得到的行比原始行少了。更糟糕的是,如果我向IN (val1, ...)
添加更多值,则会得到更少行。为什么会这样?
答案 0 :(得分: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'的行越少:这就是您所观察到的。
您仍然可以使用它:对至少有一个extra1 = 'val1'
报告row_name
,将ORDER BY
更改为:
ORDER BY row_name, (extra1 <> 'val1')
在顶部排序“ val1”。该boolean
表达式的说明(带有更多链接):
在排序顺序不确定时,仍然可以任意选择其他“额外”列。
交叉表基础知识: