繁体   English   中英

如何使用不同的分隔符

[英]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

sql小提琴演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM