假设我在postgres中有一个简单的表格如下:
+--------+--------+----------+
| Car | Pet | Name |
+--------+--------+----------+
| BMW | Dog | Sam |
| Honda | Cat | Mary |
| Toyota | Dog | Sam |
| ... | ... | ... |
我想运行一个sql查询,它可以返回第一列中的列名和第二列中的唯一值。例如:
+--------+--------+
| Col | Vals |
+--------+--------+
| Car | BMW |
| Car | Toyota |
| Car | Honda |
| Pet | Dog |
| Pet | Cat |
| Name | Sam |
| Name | Mary |
| ... | ... |
-- Query 4b. (104 ms, 128 ms)
select distinct unnest( array_agg(a)||
array_agg(b)||
array_agg(c)||
array_agg(d) )
from t ;
但我不太了解代码,知道如何将列名追加到另一列中。
I also found a query that can return the column names in a table.可能是上面显示的“查询4b”的子查询?
答案 0 :(得分:4)
SELECT distinct
unnest(array['car', 'pet', 'name']) AS col,
unnest(array[car, pet, name]) AS vals
FROM t
order by col
答案 1 :(得分:2)
将设置返回函数放在SELECT
列表中并且SQL标准中不允许这样做的风格很糟糕。 Postgres支持它的历史原因,但自LATERAL
引入Postgres 9.3后,它已经基本上过时了。我们也可以在这里使用它:
SELECT x.col, x.val
FROM tbl, LATERAL (VALUES ('car', car)
, ('pet', pet)
, ('name', name)) x(col, val)
GROUP BY 1, 2
ORDER BY 1, 2;
您会在the very same question on dba.SE you already found yourself下找到这种LATERAL (VALUES ...)
技术。只是不要在第一个答案时停止阅读。
直到Postgres 9.4 还有一个例外:" parallel unnest"需要在SELECT
列表中组合多个集合返回函数。 Postgres 9.4带来了new variant of unnest()
来消除这种必要性。更多:
如果返回行的数量对于SELECT列表中的所有set-returns函数不应完全相同,则新函数也不会脱轨成笛卡尔积,这是一种非常奇怪的行为。新语法变体应优先于现在过时的变体:
SELECT DISTINCT x.*
FROM tbl t, unnest('{car, pet, name}'::text[]
, ARRAY[t.car, t.pet, t.name]) AS x(col, val)
ORDER BY 1, 2;
也比两个unnest()
并行呼叫更短,更快。
返回:
col | val
------+--------
car | BMW
car | Honda
car | Toyota
name | Mary
name | Sam
pet | Cat
pet | Dog
DISTINCT
或GROUP BY
,对任务都有好处。
答案 2 :(得分:1)
JSON functions
row_to_json()
和json_each_text()
您无法指定列的数量和名称:
select distinct key as col, value as vals
from (
select row_to_json(t) r
from a_table t
) t,
json_each_text(r)
order by 1, 2;