我有這個表其他一些列一起:從表中的行創建兩個colums
months amount
-----------------
Jan 100
Feb 200
Jan 400
我想,這樣它是這樣來創建此表的視圖:
Jan Feb
--------------------
100 200
400 0
我搜索了它,並得到PL/SQL解決方案不能完成只有SQL查詢? 謝謝
我有這個表其他一些列一起:從表中的行創建兩個colums
months amount
-----------------
Jan 100
Feb 200
Jan 400
我想,這樣它是這樣來創建此表的視圖:
Jan Feb
--------------------
100 200
400 0
我搜索了它,並得到PL/SQL解決方案不能完成只有SQL查詢? 謝謝
首先確保,您有可用交叉
CREATE EXTENSION tablefunc;
爲了得到你想要的交叉表至少需要三列
如:
name months amount
-------------------------
Helga Jan 100
Helga Feb 200
Bernd Jan 400
然後創建你的Crosstable是這樣的:
SELECT * FROM
crosstab('SELECT name, month, amount from temp')
AS ct(name varchar, jan int, feb int);
name jan feb
--------------------------
Helga 100 200
Bernd 400
如果你將不得不列每個月,堅持例子作爲manual
create table sales(year int, month int, qty int);
insert into sales values(2007, 1, 1000);
insert into sales values(2007, 2, 1500);
insert into sales values(2007, 7, 500);
insert into sales values(2007, 11, 1500);
insert into sales values(2007, 12, 2000);
insert into sales values(2008, 1, 1000);
select * from crosstab(
'select year, month, qty from sales order by 1',
'select m from generate_series(1,12) m'
) as (
year int,
"Jan" int,
"Feb" int,
"Mar" int,
"Apr" int,
"May" int,
"Jun" int,
"Jul" int,
"Aug" int,
"Sep" int,
"Oct" int,
"Nov" int,
"Dec" int
);
year | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec
------+------+------+-----+-----+-----+-----+-----+-----+-----+-----+------+------
2007 | 1000 | 1500 | | | | | 500 | | | | 1500 | 2000
2008 | 1000 | | | | | | | | | | |
(2 rows)
說明沒有與你的邏輯出了問題,怎麼會SQL知道它應該是
Jan Feb
100 200
400 0
,而不是
Jan Feb
400 200
100 0
我已經採取這意味着列應以升序排列,(除FO r其中的值是0,因爲沒有足夠的數據):
WITH CTE AS
( SELECT Month, Amount, ROW_NUMBER() OVER(PARTITION BY Month ORDER BY Amount) AS RowNumber
FROM T
)
SELECT COALESCE(Jan.Amount, 0) AS Jan,
COALESCE(Feb.Amount, 0) AS Feb,
COALESCE(Mar.Amount, 0) AS Mar
FROM ( SELECT RowNumber, Amount
FROM CTE
WHERE Month = 'Jan'
) jan
FULL JOIN
( SELECT RowNumber, Amount
FROM CTE
WHERE Month = 'Feb'
) feb
ON feb.RowNumber = Jan.RowNumber
FULL JOIN
( SELECT RowNumber, Amount
FROM CTE
WHERE Month = 'Mar'
) Mar
ON Mar.RowNumber = Jan.RowNumber
這一邏輯已經SQL Fiddle過測試,但我相當肯定,你可以申請使用ROWNUMBER來交叉來解決你的問題目前正與CROSSTAB合作。 ROWNUMBER成爲你rowvalue,我從來沒有使用交叉表中Postgres的,但我認爲你會落得這樣的:
SELECT *
FROM CROSSTAB('SELECT ROW_NUMBER() OVER(PARTITION BY Month ORDER BY Amount) AS RowNumber, Month, Amount FROM T',
'SELECT DISTINCT ROW_NUMBER() OVER(PARTITION BY Month ORDER BY Amount) AS RowNumber FROM T')
AS (RowNumber INT, Jan INT, Feb INT, Mar INT);
我不能得到這個工作的SQL小提琴,但我認爲這是因爲CROSSTAB ISN因爲即使Postgres文檔中的示例在SQL Fiddle上也不起作用。
順便說一句 - 我剛剛添加交叉表函數到sql小提琴。 –
您使用的是什麼版本的SQL?如果您知道列和2008+,則可以使用此http://msdn.microsoft.com/zh-cn/library/ms177410(v=sql.105).aspx –
實際上它適用於PostgreSQL – HakimuddinHussain
http:// www .postgresql.org/docs/9.1/static/tablefunc.html - Crosstab是否可用? –