假设我有此查询以供查看:
select a.name as Author,b.name as Book
from a
left join b on a.id = b.a_id
并产生以下输出:
Brandon Sanderson Mistborn
Brandon Sanderson Way of Kings
Brandon Sanderson Steelheart
Patrick Rothfuss The Wise Man's Fear
Patrick Rothfuss The Name of the Wind
到目前为止一切都很好,但我想将重复项隐藏在左行:
Brandon Sanderson Mistborn
Way of Kings
Steelheart
Patrick Rothfuss The Wise Man's Fear
The Name of the Wind
这使IMO的阅读更加容易,这就是我要用于此视图的格式。
我该如何实现?
答案 0 :(得分:1)
好吧,这可以通过window function
来实现,如果您现在使用的数据库支持此功能,例如PostgreSQL或高版本(8.0+)的MySQL,则可以编写如下的SQL:>
select * from books;
author | book
-------------------+----------------------
Brandon Sanderson | Mistborn
Brandon Sanderson | Way of Kings
Brandon Sanderson | Steelheart
Patrick Rothfuss | The Wise Man’s Fear
Patrick Rothfuss | The Name of the Wind
(5 rows)
select
case when row_number() over(partition by author order by book) > 1 then null else author end as author,
book
from
books;
author | book
-------------------+----------------------
Brandon Sanderson | Mistborn
| Steelheart
| Way of Kings
Patrick Rothfuss | The Name of the Wind
| The Wise Man's Fear
(5 rows)
with tmp as (
select
author,
book,
row_number() over(partition by author order by book) as sort
from
books
)
select
case when sort>1 then null else author end as th_author,
book
from
tmp
order by
author,sort;
th_author | book
-------------------+----------------------
Brandon Sanderson | Mistborn
| Steelheart
| Way of Kings
Patrick Rothfuss | The Name of the Wind
| The Wise Man‘s Fear
或者数据库不支持window function
,您可以编写如下内容:
with named_book as (
select
author,
min(book) as book
from
books
group by
author
)
select
b.author,
a.book
from
books a
left join
named_book b on a.book = b.book
order by
a.author,a.book;
author | book
-------------------+----------------------
Brandon Sanderson | Mistborn
| Steelheart
| Way of Kings
Patrick Rothfuss | The Name of the Wind
| The Wise Man's Fear
(5 rows)
答案 1 :(得分:1)
这不是您通常在SQL中要做的事情。表格具有行和列,并且-通常-一行中的值sin应该独立于其他行。
您可以使用row_number()
进行此操作,请注意排序标准:
select (case when 1 = row_number() over (partition by a.id order by b.name)
then a.name
end) as Author,
b.name as Book
from a left join
b
on a.id = b.a_id
order by a.id, b.name;
外部order by
键与partition by
和order by
子句中的键相匹配非常重要。
您可能会发现为每个作者创建一行更为有用。语法因数据库而异,但我认为标准功能是listagg()
:
select a.name as Author,
listagg(b.name, '; ') within group (order by b.name) as Book
from a left join
b
on a.id = b.a_id
group by a.name;