BG Development


Страници: (4) 1 [2] 3 4   ( Първото ново мнение ) Reply to this topicStart new topicStart Poll

> SQL Monday
Gamma Goblin
Публикувано на: 19-08-2019, 19:59
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 4014
Регистриран на: 21.02.18



Да - трябва да се групира по клиент и категория, което означава да се направят почти всички джойнове

Прикачена картинка (Кликнете на картинката, за да я увеличите!)
Прикачена картинка
PMEmail PosterUsers Website
Top
dvader
Публикувано на: 19-08-2019, 20:12
Quote Post


Group Icon
Име: Валерий Тодоров
Група: VIP
Ранг: Почетен член

Мнения: 5419
Регистриран на: 12.07.05



Имаш три таблици - rentals, inventory, film_category за вътрешното куери и после джойн с сustomer и film за самите резултати.


--------------------
I find your lack of faith disturbing
PM
Top
Gamma Goblin
Публикувано на: 19-08-2019, 20:15
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 4014
Регистриран на: 21.02.18



да, така е малко по-бързо (150мс срещу 100):

CODE


EXPLAIN (ANALYZE, BUFFERS)
with T as (
   select customer, category, rentals, max(X.rentals) over (partition by X.customer) as max_rentals
   from (
            select r.customer_id as customer, fc.category_id as category, count(*) as rentals
            from rental r
                     join inventory i on i.inventory_id = r.inventory_id
                     join film f on f.film_id = i.film_id
                     join film_category fc on fc.film_id = f.film_id
            group by r.customer_id, fc.category_id
        ) as X
)
select c.email, cat.name
from T
        join category cat on cat.category_id = T.category
        join customer c on c.customer_id = T.customer
where T.rentals = T.max_rentals
order by c.email asc, cat.name asc;
PMEmail PosterUsers Website
Top
thrawn
Публикувано на: 19-08-2019, 20:30
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 3864
Регистриран на: 17.01.17



//off
С какво генерира схемата?
PMEmail Poster
Top
dvader
Публикувано на: 19-08-2019, 20:35
Quote Post


Group Icon
Име: Валерий Тодоров
Група: VIP
Ранг: Почетен член

Мнения: 5419
Регистриран на: 12.07.05



Аз го докарах до нещо такова, ама не знам дали е вярно icon_wink.gif

CODE
SELECT customer.email,
      category.name
 FROM customer
      JOIN
      (
          SELECT rental.customer_id,
                 film_category.category_id,
                 count( * ) AS total
            FROM rental
                 JOIN
                 inventory ON rental.inventory_id = inventory.inventory_id
                 JOIN
                 film_category ON inventory.film_id = film_category.film_id
           GROUP BY rental.customer_id,
                    category_id
      )
      AS Statistics ON customer.customer_id = Statistics.customer_id
      JOIN
      category ON category.category_id = Statistics.category_id
GROUP BY category.category_id
HAVING MAX(Statistics.total)
ORDER BY customer.email;


Това мнение е било редактирано от dvader на 19-08-2019, 20:44


--------------------
I find your lack of faith disturbing
PM
Top
Gamma Goblin
Публикувано на: 19-08-2019, 20:39
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 4014
Регистриран на: 21.02.18



QUOTE (thrawn @ 19-08-2019, 20:30)
//off
С какво генерира схемата?

копирах я от readme-то в github
PMEmail PosterUsers Website
Top
Gamma Goblin
Публикувано на: 20-08-2019, 05:57
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 4014
Регистриран на: 21.02.18



QUOTE (dvader @ 19-08-2019, 20:35)
Аз го докарах до нещо такова, ама не знам дали е вярно icon_wink.gif

CODE
SELECT customer.email,
      category.name
 FROM customer
      JOIN
      (
          SELECT rental.customer_id,
                 film_category.category_id,
                 count( * ) AS total
            FROM rental
                 JOIN
                 inventory ON rental.inventory_id = inventory.inventory_id
                 JOIN
                 film_category ON inventory.film_id = film_category.film_id
           GROUP BY rental.customer_id,
                    category_id
      )
      AS Statistics ON customer.customer_id = Statistics.customer_id
      JOIN
      category ON category.category_id = Statistics.category_id
GROUP BY category.category_id
HAVING MAX(Statistics.total)
ORDER BY customer.email;

CODE
[2019-08-20 06:56:23] [42804] ERROR: argument of HAVING must be type boolean, not type bigint
PMEmail PosterUsers Website
Top
thrawn
Публикувано на: 20-08-2019, 06:13
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 3864
Регистриран на: 17.01.17



CODE
HAVING MAX(Statistics.total) = Statistics.total
PMEmail Poster
Top
Gamma Goblin
Публикувано на: 20-08-2019, 06:27
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 4014
Регистриран на: 21.02.18



QUOTE (thrawn @ 20-08-2019, 06:13)
CODE
HAVING MAX(Statistics.total) = Statistics.total

за PG не е достатъчно, защото има стриктен GROUP BY:

CODE
[42803] ERROR: column "customer.email" must appear in the GROUP BY clause or be used in an aggregate function Position: 8


Ще излезе и същия проблем за customer.email, Statistics.total,
PMEmail PosterUsers Website
Top
thrawn
Публикувано на: 20-08-2019, 07:39
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 3864
Регистриран на: 17.01.17



Проблемът е вече в селектът, просто добави email и name в group by клаузата.
В случая е хубаво join -а да се прави чак след последното групиране (щом ще се ползват две). Така ще избегнеш генериране на данни които така или иначе изхвърлят.

Пробвай моя вариант от предната страница, но си линк таблиците за да се събереш до категорията в СТЕ. Чак когато получиш ИД-тата на двата обекта закачай детайлите.

Това мнение е било редактирано от thrawn на 20-08-2019, 07:39
PMEmail Poster
Top
0 потребители преглеждат тази тема в момента (0 гости, 0 анонимни потребители)
Потребители, преглеждащи темата в момента:

Topic Options Страници: (4) 1 [2] 3 4  Reply to this topicStart new topicStart Poll

 


Copyright © 2003-2019 | BG Development | All Rights Reserved
RSS 2.0