我需要(安全地)处理有< 5“评论”的产品(甚至没有)。此外,能够定义“评论”的顺序很重要。我更喜欢一个适用于SQL Server和PostgreSQL的解决方案(稍作修改)。我愿意使用PIVOT作为最后的手段,但从我所看到的它不会做我想做的事。
表1
id ,产品
1,'产品1'
2,'产品2'
表2
id ,审核
1,'回顾#1a'
1,'回顾#1b'
1,'回顾#1c'
1,'回顾#1d'
1,'评论#1e'
1,'回顾#1f'
2,'回顾#2a'
2,'回顾#2b'
2,'回顾#2c'
2,'回顾#2d'
2,'回顾#2e'
2,'回顾#2f'
结果
1,'产品1','评论#1a','评论#1b','评论#1c','评论#1d','评论#1e'
2,'产品2','评论#2a','评论#2b','评论#2c','评论#2d','评论#2e'
答案 0 :(得分:1)
试试这个(调整以引用适当的东西):
这个想法是......使用row_number()来获得每个产品最多5个评论。然后转动结果,然后执行左连接以获取产品详细信息(包括那些没有任何评论的内容)。
with top5reviews as
(
select *
from
(
select
productid, review
, row_number() over (partition by productid order by reviewid) as reviewnum
from reviews
) r
where reviewnum <= 5
)
, pivotted as
(
select productid, [1] as review1, [2] as review2, [3] as review3, [4] as review4, [5] as review5
from top5reviews r
pivot
(max(review) for reviewnum in ([1],[2],[3],[4],[5])) p
)
select *
from products p
left join
pivotted r
on p.productid = r.productid
答案 1 :(得分:0)
PIVOT与ROW_NUMBER()结合使用即可。以下是SQL Server的Northwind示例数据库中的示例。如果您对如何调整它有任何疑问,请询问并发布表和样本数据的CREATE TABLE和INSERT语句。
我使用了CTE,因为它很方便,但可以将其重写为派生表。
请注意,使用MAX只是为了满足旋转聚合的PIVOT语法要求。 MIN也可以。
with Ranked(EmployeeID,Freight,rk) as (
select
EmployeeID,
Freight,
row_number() over (
partition by EmployeeID
order by Freight desc, OrderID
)
from Orders
)
select EmployeeID, [1],[2],[3],[4],[5]
from (select * from Ranked where rk <= 5) as T pivot (
max(Freight) for rk in ([1],[2],[3],[4],[5])
) AS P;
答案 2 :(得分:-1)
请注意,当OP提供它时,table2中的id列是table1的外键。
alter table table2 add column rank int;
-- better reviews have lower ranks
alter table table2 constraint table2idrank unique( id, rank) ;
-- ranks are unique within a product
-- note, ranks must also be consecutive
create view min_rank_review as
select id, min(rank) as rank
from table2
group by id;
create view product_review_pivot as
select a.product, b.review as r1, c.review as r2, d.review as r3, e.review as r4
from
table1 a left outer join table2 b on (a.id = b.id)
join min_rank_review m on (b.id = m.id and b.rank = m.rank)
left outer join table2 c on (c.id = b.id and c.rank + 1 = b.rank)
left outer join table2 d on (d.id = c.id and d.rank + 1 = c.rank)
left outer join table2 e on (e.id = f.id and e.rank + 1 = d.rank);
select * from product_review_pivot;
编辑:我认为down-mods是因为这不起作用。但是将left outer join min_rank_review m on (b.id = m.id and b.rank = m.rank)
替换为join min_rank_review m on (b.id = m.id and b.rank = m.rank)
(并进行一些其他小修正)并且它可以正常工作。
对不起,我的办公室伙伴想回家,并没有给我时间去校对。 :)
插入以下数据:
insert into table1 ( product ) values ('a'), ('b');
insert into table2(id, review, rank) values
(1, 'r1', 1 ), (1, 'r2', 2), (1, 'r3', 3 ),
(1, 'r4', 4), (1, 'r5', 5 ), (2, 'rr2', 1);
我得到以下输出(在MySQL 5中):
mysql> select * from product_review_pivot;
+---------+------+------+------+------+
| product | r1 | r2 | r3 | r4 |
+---------+------+------+------+------+
| a | r1 | r2 | r3 | r4 |
| b | rr2 | NULL | NULL | NULL |
+---------+------+------+------+------+
(非连续排名的解决方案留作练习。)