我有一个看起来像这样的视图
value1count value2count value3count
----------------------------------------
25 35 55
我需要将列标题转换为行,所以我需要它看起来像
Values Count
-----------------------------
value1count 25
value2count 35
value3count 55
我可以通过选择单个列名作为第一列,将数据作为第二列,然后为所有列执行相同的联合来完成此操作。
有更好的方法吗? 我使用的是PosgreSQL 8.1,因此没有透视操作符可以使用。
感谢您的回复。
答案 0 :(得分:28)
交叉表只能与您需要的相反,但这应该对您有所帮助:
首先创建8.4中包含的unnest()
函数,有关说明,请参阅here。
然后你可以这样做(基于this帖子):
SELECT
unnest(array['value1Count', 'value2Count', 'value3Count']) AS "Values",
unnest(array[value1Count, value2Count, value3Count]) AS "Count"
FROM view_name
ORDER BY "Values"
我可以验证这是否适用于8.4,但因为我没有8.1,所以我不能保证它会有相同的效果。
答案 1 :(得分:5)
我使用hstore
的功能实现了您的目标:
SELECT (x).key, (x).value
FROM
( SELECT EACH(hstore(t)) as x
FROM t
) q;
您的“待爆炸”视图或表格(此处称为t
)中可能有多行,您可能需要在中间表q
中插入一个附加标识符,例如:
SELECT id, (x).key, (x).value
FROM
( SELECT id, EACH(hstore(t)) as x
FROM t
) q;
答案 2 :(得分:3)
我希望做一些与此类似的事情,以便更轻松地处理来自bash脚本的表信息。结果很容易告诉psql将表列显示为行:
psql mydbname -x -A -F= -c "select * from blah where id=123"
-x
是产出的关键。-A
删除了额外的间距。-F=
会在列名和值之间用|
替换=
。这当然不适用于SQL,它只会修改psql
格式化输出的方式。
答案 3 :(得分:0)
我有类似的情况。我将我的查询包装在一个with语句中,然后为每一行做了一堆UNION ALL
个。在我的情况下,如果我有多个记录,那么ncm_id会有所不同,所以我继续将其添加到我的结果集中的列列表中。这可能不是最好的方法,但它适用于我的用例。
WITH query_a AS (
SELECT
fin_item.item_number || ' - ' || fin_item.item_descrip1 fin_item,
fin_ls.ls_number,
ls_sort.sortby_employeeid,
ls_sort.ncm_id,
ls_sort.created_at,
ls_sort.updated_at,
ls_sort.sort_qty,
ls_sort.initial_scan_time,
ls_sort.ncm_scan_time,
ls_sort.badge_scan_time,
ls_sort.computer_name,
ls_sort.number_of_ops,
ls_sort.ncm_item_scan_time,
sort_by.name sort_by,
tblncm.instructions,
tblncm.ncm_comments
FROM public.item AS fin_item
INNER JOIN public.ls AS fin_ls ON fin_item.item_id = fin_ls.ls_item_id
INNER JOIN stone.ls_sort ON fin_ls.ls_id = ls_sort.ls_id
INNER JOIN stone.vw_mssql_employees AS sort_by ON ls_sort.sortby_employeeid = sort_by.employeeid
INNER JOIN stone.tblncm ON ls_sort.ncm_id = tblncm.ncm_id
LEFT JOIN stone.equips AS mach_equips ON ls_sort.mach_equip_id = mach_equips.id
LEFT JOIN stone.equips AS mold_equips ON ls_sort.mold_equip_id = mold_equips.id
WHERE 1 = 1
AND fin_ls.ls_number ILIKE 'S143027526190' || '%'
)
SELECT *
FROM (
(SELECT 'fin_item' my_column, fin_item::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a)
UNION ALL
(SELECT 'ls_number' my_column, ls_number::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a)
UNION ALL
(SELECT 'sortby_employeeid' my_column, sortby_employeeid::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a)
UNION ALL
(SELECT 'ncm_id' my_column, ncm_id::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a)
UNION ALL
(SELECT 'created_at' my_column, created_at::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a)
UNION ALL
(SELECT 'updated_at' my_column, updated_at::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a)
UNION ALL
(SELECT 'sort_qty' my_column, sort_qty::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a)
UNION ALL
(SELECT 'initial_scan_time' my_column, initial_scan_time::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a)
UNION ALL
(SELECT 'ncm_scan_time' my_column, ncm_scan_time::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a)
UNION ALL
(SELECT 'badge_scan_time' my_column, badge_scan_time::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a)
UNION ALL
(SELECT 'computer_name' my_column, computer_name::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a)
UNION ALL
(SELECT 'number_of_ops' my_column, number_of_ops::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a)
UNION ALL
(SELECT 'ncm_item_scan_time' my_column, ncm_item_scan_time::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a)
UNION ALL
(SELECT 'sort_by' my_column, sort_by::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a)
UNION ALL
(SELECT 'instructions' my_column, instructions::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a)
UNION ALL
(SELECT 'ncm_comments' my_column, ncm_comments::TEXT my_value, ncm_id::TEXT my_ncm FROM query_a)
) as query_guy
ORDER BY my_ncm;
答案 4 :(得分:0)
我可能不明白...但是我这样做的方法是还选择DISTINCT,然后选择所需的平均列值。像这样:
Sub Owners()
Sheets("Start").Activate
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If ws.Name <> ThisWorkbook.ActiveSheet.Name Then
ws.Visible = xlSheetHidden
End If
Next ws
With Worksheets("Start")
Dim stateMatch As Variant
stateMatch = Application.Match(.Range("B2").Value, Sheets("List").Range("K2:K32"), 0)
Dim numOwnerMatch As Variant
numOwnerMatch = Application.Match(.Range("B3").Value, Sheets("List").Range("D2:D3"), 0)
If IsNumeric(stateMatch) And IsNumeric(numOwnerMatch) Then
If numOwnerMatch = 1 Then
Worksheets("1st OwnerStatement").Visible = True
Worksheets("1st OwnerPPW").Visible = True
End If
If numOwnerMatch = 2 Then
Worksheets("1st OwnerStatement").Visible = True
Worksheets("2nd OwnerStatement").Visible = True
Worksheets("1st OwnerPPW").Visible = True
Worksheets("2nd OwnerPPW").Visible = True
End If
End With
End Sub
这是纽约市机动车碰撞数据。