Выполнение выборочного запроса для 1 результата на значение строки (с несколькими значениями строк на таблицу) - PullRequest
0 голосов
/ 06 октября 2019

Я заканчиваю проект класса SQL и могу найти результаты, которые я хочу, но не представил правильно, может кто-нибудь предложить способ обновить мой код, чтобы он возвращался правильно?

Задача - вернуть любимый жанр каждому клиенту. Приведенный ниже код возвращает все покупки по каждому клиенту, сгруппированные по жанрам, а затем упорядоченные по количеству. Поэтому мне нужна только первая строка для каждого клиента из этой таблицы.

Я предполагаю, что мне нужно каким-то образом вложить запрос, который находит группировку, которая у меня есть для каждого клиента, и затем возвращает только первую строку или LIMIT 1 * 1005. *

SELECT cust.First_Name, cust.Last_Name, genre.GenreName, COUNT(GenreID)
FROM Play_List_Invoice as invoice
JOIN Play_List_Track as track USING (trackID)
JOIN Play_List_Genre as genre USING (GenreID)
JOIN Play_List_Customer as cust USING (customerID)
GROUP BY invoice.customerID, genreID
ORDER BY invoice.customerID, COUNT(GenreID) DESC;

===RESULTS
First_Name  Last_Name   GenreName   COUNT(GenreID)
    Luís        Gonçalves   Rock         23
    Luís        Gonçalves   Latin        15
    Luís        Gonçalves   Classical    8
    Leonie      Köhler      Rock         27
    Leonie      Köhler      Blues        15
    Leonie      Köhler      Soundtrack   5
    François    Tremblay    Classical   15
    François    Tremblay    Metal       12
    François    Tremblay    Alternative & Punk  6

======= ОБНОВЛЕНИЕ === Я думал, что это может быть окно. Спасибо за чаевые! У меня нет опыта работы с предложениями WITH. Я читал, что это блок подзапроса с именем или, я бы сказал, временная таблица.

Я построил:

with q as (
      SELECT cust.CustomerId, cust.First_Name, cust.Last_Name, genre.GenreName, COUNT(GenreID) as cnt
      SELECT cust.First_Name, cust.Last_Name, genre.GenreName, COUNT(GenreID)
        FROM Play_List_Invoice as invoice
        JOIN Play_List_Track as track USING (trackID)
        JOIN Play_List_Genre as genre USING (GenreID)
        JOIN Play_List_Customer as cust USING (customerID)
        GROUP BY invoice.customerID, genreID
        ORDER BY invoice.customerID, COUNT(GenreID) DESC
     )
select q.*
from (select q.*,
             row_number() over (partition by customerId order by cnt desc) as seqnum
      from q
     ) q
where seqnum = 1;

НоЯ получаю ошибку в СО. Не уверен, в чем проблема. Я даже попытался добавить имя q (topGenre) без удачи. Я попытался переписать его как вложенный

select * from
(
    select cust.CustomerId, cust.First_Name, cust.Last_Name
        , genre.GenreName
        , row_number() over (partition by customerId order by cnt desc) as seqnum 

    from (SELECT cust.CustomerId, cust.First_Name, cust.Last_Name
        , genre.GenreName, COUNT(GenreID) as cnt
    FROM Play_List_Invoice as invoice
    JOIN Play_List_Track as track USING (trackID)
    JOIN Play_List_Genre as genre USING (GenreID)
    JOIN Play_List_Customer as cust USING (customerID)
    GROUP BY invoice.customerID, genreID
    ORDER BY invoice.customerID, COUNT(GenreID) DESC
     ) as this
) as results
where seqnum = 1; 

Но это возвращает проблему с "(." Я использую jupyter HUB, поэтому обратной связи об ошибках немного не хватает.

1 Ответ

0 голосов
/ 06 октября 2019

Вы можете использовать оконные функции:

with q as (
      SELECT cust.CustomerId, cust.First_Name, cust.Last_Name, genre.GenreName, COUNT(GenreID) as cnt
      . . .  <rest of your query here>
     )
select q.*
from (select q.*,
             row_number() over (partition by customerId order by cnt desc) as seqnum
      from q
     ) q
where seqnum = 1;
...