Скрыть данные для всех, кроме первой строки в левом столбце соединения - PullRequest
0 голосов
/ 05 июня 2019

Допустим, у меня есть этот запрос для просмотра:

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, и мне нужно именно это форматирование для этого представления.

Как мне этого добиться?

Ответы [ 2 ]

1 голос
/ 05 июня 2019

Это не то, что вы обычно делаете в 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;
1 голос
/ 05 июня 2019

Ну, это может быть реализовано с помощью window function, если база данных, которую вы используете сейчас, поддерживает эту функцию, такую ​​как PostgreSQL или MySQL высокой версии (8.0+), вы можете написать 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...