【问题标题】:Sample DVD Rental database, find a customers favorite actor样本 DVD 租赁数据库,找到客户最喜欢的演员
【发布时间】:2018-07-01 20:39:24
【问题描述】:

我一直在努力提高我的 SQL 连接技能。我正在使用经典的示例 DVD 租赁数据库(可以找到 here )。我试图通过计算该演员在客户租用的所有电影中的出场次数来确定客户最喜欢的演员。

现在我有一个包含 3 个子查询的怪物查询。

SELECT email, actor.last_name, count(actor.last_name)
FROM (SELECT email, actor_id
      FROM (SELECT email, film_id
         FROM (SELECT email, inventory_id
              FROM customer as cu
              JOIN rental ON cu.customer_id = rental.customer_id
              ORDER BY email) as sq
         JOIN inventory ON sq.inventory_id = inventory.inventory_id) as sq2
      JOIN film_actor ON sq2.film_id = film_actor.film_id) as sq3
JOIN actor ON sq3.actor_id = actor.actor_id
GROUP BY email, actor.last_name
ORDER BY COUNT(actor.last_name) DESC;

我最终得到的是完整的电子邮件列表、演员的姓氏以及出场总数,就像这样 - 电子邮件

email                               actor.last_name     count
"debra.nelson@sakilacustomer.org"   "Nolte"             "12"
"nathan.runyon@sakilacustomer.org"  "Guiness"           "11"
"margie.wade@sakilacustomer.org"    "Temple"            "11"
"marsha.douglas@sakilacustomer.org" "Kilmer"            "11"
"veronica.stone@sakilacustomer.org" "Nolte"             "11"
"wendy.harrison@sakilacustomer.org" "Willis"            "10"  etc

如何修改我的查询,以便我只获取每封电子邮件的顶级参与者,有没有办法让这个查询更简单并产生相同的结果?

【问题讨论】:

    标签: sql join subquery


    【解决方案1】:

    在简化此查询方面,请记住使用表别名。

    您的查询充满了不必要的子查询,可以归结为:

            SELECT cu.email, act.last_name, count(act.last_name)
    
              FROM customer as cu
              JOIN rental as ren ON cu.customer_id = ren.customer_id
              JOIN inventory as inv ON ren.inventory_id = inv.inventory_id
              JOIN film_actor as fil ON inv.film_id = fil.film_id
              JOIN actor as act ON act.actor_id = fil.actor_id
              group by cu.email,act.last_name
    

    接下来,在获得每个电子邮件地址的最高参与者方面,我们可以应用 row_number() 窗口函数,然后子查询 where row number = 1 以缩小结果范围:

            Select x.email,x.last_name,x.count from (
            SELECT cu.email, act.last_name, count(act.last_name)
            ,row_number() over(partition by email order by COUNT(act.last_name) DESC )
              FROM customer as cu
              JOIN rental as ren ON cu.customer_id = ren.customer_id
              JOIN inventory as inv ON ren.inventory_id = inv.inventory_id
              JOIN film_actor as fil ON inv.film_id = fil.film_id
              JOIN actor as act ON act.actor_id = fil.actor_id
              group by cu.email,act.last_name
              ) as x 
             where row_number = 1
             ORDER BY x.count DESC;
    

    【讨论】:

    • 啊我刚刚了解了joins on joins。很有意义。我不知道那个 row_number() 或 over() 或分区函数。我会查这些的。感谢您的回答!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-30
    • 1970-01-01
    • 2023-01-03
    • 2018-12-03
    • 2012-07-24
    • 2019-03-25
    • 1970-01-01
    相关资源
    最近更新 更多