Sql 筛选对具有多个值的crosstab()查询结果的意外影响
我有一个Sql 筛选对具有多个值的crosstab()查询结果的意外影响,sql,postgresql,pivot-table,crosstab,Sql,Postgresql,Pivot Table,Crosstab,我有一个crosstab()查询,与我上一个问题中的查询类似: 常见的情况是使用多个值过滤extra1字段:extra1 IN(value1,value2…)。对于extra1过滤器中包含的每个值,我添加了一个排序表达式,如上面提到的帖子所示。结果查询如下所示: SELECT * FROM crosstab( 'SELECT row_name, extra1, extra2..., another_table.category, value FROM table t JOIN
crosstab()
查询,与我上一个问题中的查询类似:常见的情况是使用多个值过滤
extra1
字段:extra1 IN(value1,value2…
)。对于extra1
过滤器中包含的每个值,我添加了一个排序表达式,如上面提到的帖子所示。结果查询如下所示:
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, val2, ...) --> more values
ORDER BY row_name ASC, (extra1 <> val1), (extra1 <> val2)', ... --> more ordering expressions
'SELECT category_name FROM category_name WHERE field = certain_value'
) AS ct(extra1, extra2...)
WHERE extra1 = val1; --> condition on the result
这是我们的分类表:
+-------------+--------+
| category_id | value |
+-------------+--------+
| 1 | Cat1 |
| 2 | Cat2 |
| 3 | Cat3 |
+-------------+--------+
使用交叉表
,可以得到如下表格:
+----------+--------+--------+------+------+------+
| row_name | Extra1 | Extra2 | cat1 | cat2 | cat3 |
+----------+--------+--------+------+------+------+
| Name1 | 10 | A | 100 | 100 | |
| Name2 | 11 | B | | 200 | 150 |
| Name3 | 12 | C | 120 | 150 | 150 |
+----------+--------+--------+------+------+------+
我们的想法是能够过滤结果表,这样我就可以使用extra 1
列获得结果,该列的值为10
或11
,如下所示:
+----------+--------+--------+------+------+------+
| row_name | Extra1 | Extra2 | cat1 | cat2 | cat3 |
+----------+--------+--------+------+------+------+
| Name1 | 10 | A | 100 | 100 | |
| Name2 | 11 | B | | 200 | 150 |
+----------+--------+--------+------+------+------+
问题是在我的查询中,Extra1
使用10
作为值和Extra1
使用11
作为值得到的结果大小不同。使用(Extra1 10)
我可以在Extra1
上获得该值的正确结果大小,但在11
作为值的情况下则不能
下面是一把小提琴,更详细地演示了这个问题:
所有“额外”列均从组的第一行中复制(如中所述)
使用以下选项进行筛选时:
.... WHERE extra1 = 'val1';
…在同一列上添加更多的orderby表达式是没有意义的。只有源组中至少有一个extra1='val1'
的行仍然存在
从您的各种注释中,我猜您可能希望看到extra
(在WHERE
子句中过滤的集合中)对于相同的unixdatetime
的所有不同的现有值。如果是,请在旋转前进行聚合。比如:
SELECT *
FROM crosstab(
$$
SELECT unixdatetime, x.extras, c.name, s.value
FROM (
SELECT unixdatetime, array_agg(extra) AS extras
FROM (
SELECT DISTINCT unixdatetime, extra
FROM source_table s
WHERE extra IN (1, 2) -- condition moves here
ORDER BY unixdatetime, extra
) sub
GROUP BY 1
) x
JOIN source_table s USING (unixdatetime)
JOIN category_table c ON c.id = s.gausesummaryid
ORDER BY 1
$$
, $$SELECT unnest('{trace1,trace2,trace3,trace4}'::text[])$$
) AS final_result (unixdatetime int
, extras int[]
, trace1 numeric
, trace2 numeric
, trace3 numeric
, trace4 numeric);
旁白:以下关于第二个功能参数的相关答案中给出的建议也适用于您的情况:
category\u表
。同样,短一点,快一点,但是:
SELECT *
FROM crosstab(
$$
SELECT unixdatetime, x.extras, s.gausesummaryid, s.value
FROM (
SELECT unixdatetime, array_agg(extra) AS extras
FROM (
SELECT DISTINCT unixdatetime, extra
FROM source_table
WHERE extra IN (1, 2) -- condition moves here
ORDER BY unixdatetime, extra
) sub
GROUP BY 1
) x
JOIN source_table s USING (unixdatetime)
ORDER BY 1
$$
, $$SELECT unnest('{923,924,926,927}'::int[])$$
) AS final_result (unixdatetime int
, extras int[]
, trace1 numeric
, trace2 numeric
, trace3 numeric
, trace4 numeric);
dbfiddle-在您的fiddle底部添加了我的查询。外部
条件,其中
条件只是检查每种类型的结果大小,但它不会出现在最终查询中。因此,我想获得(…)中出现在上的每个值的正确结果大小,而不仅仅是单个类型。但是,您只能在结果行中报告一个值:每组第一行中的值。如果你想报告更多,你必须在交叉表之前进行汇总。我不知道怎么做。你可以举个例子吗?@ JeasungZaleRiela:考虑添加的解决方案。你的新例子也没有帮助,因为它只显示了相同的<代码> Ext1值,用于同一个<代码> Ro.NoWord。请提供一个工作小提琴来演示实际问题。我已经用一个例子更新了你之前分享的小提琴。在最后两个查询中,您可以看到结果如何随顺序表达式而变化,这与我遇到的情况相同。我想要的是使用值1
和2
过滤extra
,但不管顺序表达式如何,都会收到正确的结果。154630800
作为unixdatetime
的源元素对于extra
、1
和2
有两个不同的值,因此结果会根据排序表达式而变化。是否可以为154630800
或类似的内容获取两行?这是我得到的唯一解决办法
SELECT *
FROM crosstab(
$$
SELECT unixdatetime, x.extras, s.gausesummaryid, s.value
FROM (
SELECT unixdatetime, array_agg(extra) AS extras
FROM (
SELECT DISTINCT unixdatetime, extra
FROM source_table
WHERE extra IN (1, 2) -- condition moves here
ORDER BY unixdatetime, extra
) sub
GROUP BY 1
) x
JOIN source_table s USING (unixdatetime)
ORDER BY 1
$$
, $$SELECT unnest('{923,924,926,927}'::int[])$$
) AS final_result (unixdatetime int
, extras int[]
, trace1 numeric
, trace2 numeric
, trace3 numeric
, trace4 numeric);