[英]How to separate the hierarchy values using distinct
我有一个带有列的表(srno, Name, Product, Amount).
这些值是
(1, Ronak, Iphone, 40000),
(2, Ronak, Iphone, 36000),
(3, Ronak, Iphone, 38000),
(4, Naman, Iphone, 40000),
(5, Naman, Ipad, 20000),
(6, Nihar, Ipad, 20000),
(7, Ronak, Ipad, 19000),
(8, Naman, Iphone, 37000),
(9, Nihar, Ipad, 40000),
我想获取不同的值,并将它们与各自的parent_id存储在另一个表中。 输出应如下所示:
(uid, name, parent_id)
(1, Ronak, NULL),
(2, Naman, NULL),
(3, Nihar, NULL),
(4, Iphone, 1),
(5, Iphone, 2),
(6, Ipad, 2),
(7, Ipad, 3),
(8, Ipad, 1),
(9, 40000, 4),
(10, 36000, 4),
(11, 38000, 4),
(12, 40000, 5),
(13, 20000, 6),
(14, 20000, 7),
(15, 19000, 8),
(16, 37000, 5),
(17, 40000, 7),
parent_id
是来自同一表的uid
谁能告诉我postgresql中的哪些查询可以实现所需的输出。 我正在使用PHP和PostgreSQL。
这样就可以了,但是每增加一列就需要一步。 我不认为使用递归CTE(也许使用辅助数组)可以做到这一点。 顺便说一句:奇怪的存储层次结构!
CREATE TABLE oldstuff
( num INTEGER NOT NULL PRIMARY KEY
, name varchar NOT NULL
, thing varchar NOT NULL
, figure INTEGER NOT NULL
, UNIQUE (name,thing,figure)
);
INSERT INTO oldstuff(num,name,thing,figure) VALUES
(1, 'Ronak', 'Iphone', 40000),
(2, 'Ronak', 'Iphone', 36000),
(3, 'Ronak', 'Iphone', 38000),
(4, 'Naman', 'Iphone', 40000),
(5, 'Naman', 'Ipad', 20000),
(6, 'Nihar', 'Ipad', 20000),
(7, 'Ronak', 'Ipad', 19000),
(8, 'Naman', 'Iphone', 37000),
(9, 'Nihar', 'Ipad', 40000);
CREATE TABLE newstuff
( num SERIAL NOT NULL PRIMARY KEY
, thing varchar NOT NULL
, parent_num INTEGER REFERENCES newstuff(num)
, UNIQUE (thing,parent_num)
);
INSERT INTO newstuff(thing)
SELECT DISTINCT os.name
FROM oldstuff os
GROUP BY os.name
;
INSERT INTO newstuff(thing,parent_num)
SELECT DISTINCT os.thing, ns.num
FROM oldstuff os
LEFT JOIN newstuff ns ON ns.thing= os.name
GROUP BY os.thing, ns.num
;
INSERT INTO newstuff(thing,parent_num)
SELECT os.figure::varchar, COALESCE(n1.num,n0.num)
FROM oldstuff os
JOIN newstuff n0 ON n0.thing= os.name AND n0.parent_num IS NULL
JOIN newstuff n1 ON n1.thing= os.thing AND n1.parent_num =n0.num
;
SELECT * FROM newstuff ;
结果:
num | thing | parent_num
-----+--------+------------
1 | Naman |
2 | Ronak |
3 | Nihar |
4 | Ipad | 1
5 | Ipad | 2
6 | Ipad | 3
7 | Iphone | 1
8 | Iphone | 2
9 | 20000 | 4
10 | 37000 | 7
11 | 40000 | 7
12 | 19000 | 5
13 | 36000 | 8
14 | 38000 | 8
15 | 40000 | 8
16 | 20000 | 6
17 | 40000 | 6
也许可以通过更简单的联接来完成,但是我认为最有效的方法是使用窗口函数:
with cte as (
select
t.Name, t.Product, t.Amount,
dense_rank() over(order by t.Name) as Name_ID,
dense_rank() over(order by t.Product, t.Name) as Product_ID,
dense_rank() over(order by t.Product, t.Name, t.Amount) as Amount_ID
from Table1 as t
), cte2 as (
select
Name, Product, Amount,
Name_ID,
max(Name_ID) over() + Product_ID as Product_ID,
max(Name_ID) over() + max(Product_ID) over() + Amount_ID as Amount_ID
from cte
)
select distinct
Name_ID as uid, Name as name, null::int as parent_id
from cte2
union all
select distinct
Product_ID as uid, Product as name, Name_ID as parent_id
from cte2
union all
select distinct
Amount_ID as uid, Amount::varchar(10) as name, Product_ID as parent_id
from cte2
order by uid, parent_id
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.