【问题标题】:SQL limit for LEFT JOINed tableLEFT JOINed 表的 SQL 限制
【发布时间】:2012-12-17 13:07:39
【问题描述】:

我有以下表格。

  1. 行业(ID、名称)
  2. Movie(id, name, industry_id) [行业有很多电影]
  3. Trailer(id, name, movie_id) [电影有很多预告片]

我需要为每个行业找到 6 个最新预告片。每部电影不需要有预告片,也可以有多个[0-n]。

CREATE TABLE industry(id int, name char(10), PRIMARY KEY (id));

CREATE TABLE movie(id int, name char(10), industry_id int, PRIMARY KEY (id),
FOREIGN KEY (industry_id) REFERENCES industry(id));

CREATE TABLE trailer(id int, name char(10), movie_id int, PRIMARY KEY (id),
FOREIGN KEY (movie_id) REFERENCES movie(id));

INSERT INTO industry VALUES (1, "sandalwood");
INSERT INTO industry VALUES (2, "kollywood");

INSERT INTO movie VALUES (1, "lakshmi", 1);
INSERT INTO movie VALUES (2, "saarathi", 2);

INSERT INTO trailer VALUES (1, "lakshmi1", 1);
INSERT INTO trailer VALUES (2, "lakshmi2", 1);
INSERT INTO trailer VALUES (3, "lakshmi3", 1);
INSERT INTO trailer VALUES (4, "lakshmi4", 1);
INSERT INTO trailer VALUES (5, "lakshmi5", 1);
INSERT INTO trailer VALUES (6, "lakshmi6", 1);

INSERT INTO trailer VALUES (7, "saarathi4", 2);
INSERT INTO trailer VALUES (8, "saarathi5", 2);
INSERT INTO trailer VALUES (9, "saarathi6", 2);

SELECT  c.*
FROM    industry a
        LEFT JOIN movie b
            ON a.id = b.industry_id
        LEFT JOIN trailer c
            ON b.id = c.movie_id
LIMIT 0, 6

| ID |     NAME | MOVIE_ID |
----------------------------
|  1 | lakshmi1 |        1 |
|  2 | lakshmi2 |        1 |
|  3 | lakshmi3 |        1 |
|  4 | lakshmi4 |        1 |
|  5 | lakshmi5 |        1 |
|  6 | lakshmi6 |        1 |

我只需要从每部电影中获取一个最近的预告片。但我得到了每部电影的所有预告片。请建议我获取SQL 声明。

【问题讨论】:

  • 您想要每部电影的最后预告片吗?我说的对吗?

标签: mysql select group-by left-join


【解决方案1】:

如果您想要 trailer 表的 id 的最新预告片,请使用以下查询:

SELECT * FROM trailer t 
INNER JOIN (SELECT movie_id, MAX(id) id 
            FROM trailer GROUP BY movie_id) AS A ON t.id = A.id 

如果您想要按日期最新的数据,请使用此查询:

SELECT * FROM trailer t 
INNER JOIN (SELECT movie_id, MAX(latestbydate) latestbydate 
            FROM trailer GROUP BY movie_id
           ) AS A ON t.movie_id = A.movie_id  AND t.latestbydate = A.latestbydate

【讨论】:

    【解决方案2】:
    SELECT i.name, m.name, MAX(t.id) AS 'Latest Trailer ID', MAX(t.name) AS 'Latest Trailer'    
    FROM industry i
    INNER JOIN movie m ON(i.id = m.industry_id)
    INNER JOIN trailer t ON(m.id = movie_id)
    GROUP BY m.id
    

    【讨论】:

      【解决方案3】:

      试试这个查询

      SELECT * FROM industry
      LEFT JOIN movie on movie.industry_id = industry.id
      LEFT JOIN (
        SELECT 
        id as T_ID,
        name as T_Name,
        movie_id
        FROM trailer 
        INNER JOIN ( SELECT 
                    MAX(id) as TID
                    FROM trailer
                    GROUP BY movie_id
                   ) as t on t.TID = trailer.id
      ) as c on c.movie_id = movie.id;
      

      这里是Demo

      【讨论】:

        【解决方案4】:

        如果您必须在 SQL 中完成这一切(而不是在您使用的任何后端或代码中,我实际上会推荐),那么您可能不得不依赖一些变量魔法。

        基本上,您需要按日期对每个预告片进行“排名”,然后按预告片所属的电影对其进行“分区”。这些词在其他一些 SQL 风格中具有实际意义(例如PL/SQL),但不幸的是在 MySQL 中没有本机功能。

        你会想要做类似于this SO post 中提到的事情。一旦你得到按movie_id划分的“等级”,你只需选择WHERE rank < 6。查询可能会变得非常混乱,并且以这种方式使用变量存在一些风险,但据我所知,这是严格使用 MySQL 查询的最佳方法

        【讨论】:

        • 不,这个查询没有那么棘手。不需要分区/排名。
        • 如果他想获得每部电影的 6 个最新预告片?我在这里看到的其他所有内容都只是最新的,不是吗?
        • 您在哪里看到他需要最新的 6 个?我读到他需要“只从每部电影中获取一个最近的预告片”。
        • @Brandon 哈哈 帖子的第二行,“我需要为每个行业找到 6 个最新的预告片。”但你是对的,后来他似乎改变了主意......
        • 其实他并没有改变主意。我只是忽略了那部分,而你忽略了我关注的部分。它们并不相互排斥,因为他说他需要每部电影的最新预告片,但需要每个行业的 6 个最新预告片。
        【解决方案5】:

        我不确定这是否适用于 MySql,因为我不记得您是否可以在 in 子句中包含子查询,但您可以尝试:

        select * from trailer
        where id in (select max(id) from trailer group by movie_id)
        

        无论它是否有效,您似乎没有在查询中使用行业表,因此加入它没有多大意义(除非您实际上试图排除没有分配任何行业的电影他们......但根据你的样本,我看起来不是你的意图)。

        如果上面的查询在MySql中不起作用,那么试试这个

        select  t.* 
        from    trailer t join
                (select max(id) id from trailer group by movie_id) t2 on t1.id = t2.id
        

        【讨论】:

        • 另外,我假设预告片表中较高的 id 是较新的。但最好像 Tarika 建议的那样实际设置一个日期列。
        【解决方案6】:

        要获取最近的跟踪,您应该包含我们可以从中获取它的日期字段列

        【讨论】:

        • 我不知道是谁投了反对票,但这是个好建议。
        • @Brandon:我同意,你不能指望在没有日期时间列的情况下查询“最新”。
        猜你喜欢
        • 1970-01-01
        • 2013-02-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-22
        • 1970-01-01
        • 2011-08-03
        相关资源
        最近更新 更多