【问题标题】:Eloquent ORM PHP retrieve movies which have related comment or reviewEloquent ORM PHP 检索有相关评论或评论的电影
【发布时间】:2017-07-30 11:49:31
【问题描述】:

我有以下带有属性的表格(和模型):

Comments:
- id
- movie_id
- date

Reviews:
- id
- movie_id
- date

Movies:
- id

将 PostgreSQL 与 Eloquent ORM 和 Slim 3 框架一起使用。 我正在尝试检索所有内容:

注意:一部电影可以有很多条评论和评论,但只有最后一条评论(BIGGEST ID)是有趣的..

包含以下内容的电影:评论或\AND 评论的日期 >(现在 - 1 天)。

尝试在带有 JOINS 的 SQL 中编写它,但发现我可以使用 Eloquent 中的一些更高级和更易于阅读的函数.. 但到目前为止,淹没在所有选项中,找不到正确的使用方法.. 有什么帮助让它尽可能地高效和轻便吗?

谢谢! 伊泰。

【问题讨论】:

  • 您能分享一下您的尝试吗?
  • 尝试在“orWhereHas”旁边使用“whereHas”,然后将“with”添加到构建器中,但它构建了一个庞大的语法,我确信它可以更有效

标签: php postgresql eloquent


【解决方案1】:

假设这些是您的表格:

CREATE TABLE movies
(
    movie_id SERIAL PRIMARY KEY,
    movie TEXT
) ;

CREATE TABLE comments
(
    comment_id SERIAL PRIMARY KEY,
    movie_id INTEGER NOT NULL REFERENCES movies(movie_id),
    comment_date DATE NOT NULL DEFAULT current_date,
    comment TEXT
) ;

CREATE TABLE reviews
(
    review_id SERIAL PRIMARY KEY,
    movie_id INTEGER NOT NULL REFERENCES movies(movie_id),
    review_date DATE NOT NULL DEFAULT current_date,
    review TEXT
) ;

以及他们的价值观:

INSERT INTO
    movies
    (movie)
VALUES
    ('2001 A Space Odissey'),
    ('Start Trek: The Wrath of Khan'),
    ('Start Trek Beyond'),
    ('The 39 steps');

INSERT INTO
    comments
    (movie_id, comment_date, comment)
VALUES
    (1, current_date,   'Best film ever'),
    (2, current_date+1, 'Not as good as 2001');

INSERT INTO reviews
    (movie_id, review_date, review)
VALUES
    (3, current_date, 'Not the best Start Trek film ever, however, the best CGI imaginable, ...') ;

实现您想要的更简单的方法是首先获取(所有)电影,以及 max(review_id)、max(comment_id),并按日期限制它们:

SELECT
    m.movie_id, m.movie, max(r.review_id) AS review_id, max(c.comment_id) AS comment_id
FROM
    movies m
    LEFT JOIN reviews r ON (r.movie_id = m.movie_id AND r.review_date >= current_date)
    LEFT JOIN comments c ON (c.movie_id = m.movie_id AND c.comment_date >= current_date) 
GROUP BY
    m.movie_id ;
电影ID |电影 | review_id | comment_id --------: | :---------------------------- | --------: | ---------: 2 |开始迷航:可汗之怒 | 空 | 2 4 | 39 步 | 空 | 空 1 | 2001 太空奥德赛 | 空 | 1 3 |开始迷航超越 | 1 | 空

从之前的查询中,我们返回链接以获取其余的评论和评论数据:

SELECT
    q.movie_id, q.movie, q.review_id, r2.review_date, r2.review, q.comment_id, c2.comment_date, c2.comment
FROM
    (SELECT
        m.movie_id, m.movie, max(r.review_id) AS review_id, max(c.comment_id) AS comment_id
    FROM
        movies m
        LEFT JOIN reviews r ON (r.movie_id = m.movie_id AND r.review_date >= current_date)
        LEFT JOIN comments c ON (c.movie_id = m.movie_id AND c.comment_date >= current_date) 
    GROUP BY
        m.movie_id
    HAVING
        -- restrict to only movies with some recent comment or review
        max(r.review_id) IS NOT NULL or max(comment_id) IS NOT NULL
    ) AS q
    LEFT JOIN reviews r2 USING(review_id)
    LEFT JOIN comments c2 USING(comment_id)
ORDER BY
    movie_id ;

结果是:

电影ID |电影 | review_id |审查日期 |评论 |评论 ID |评论日期 |评论 --------: | :---------------------------- | --------: | :------------ | :------------------------------------------------- ---------------------- | ---------: | :----------- | :----------------- 1 | 2001 太空奥德赛 | 空 | 空 | 空 | 1 | 2017-07-30 |有史以来最好的电影 2 |开始迷航:可汗之怒 | 空 | 空 | 空 | 2 | 2017-07-31 |不如2001 3 |开始跋涉超越 | 1 | 2017-07-30 |不是最好的 Start Trek 电影,但是,最好的 CGI 可以想象,... | 空 | 空 | 空

您可以在 dbfiddle here

中测试所有这些

注意:老实说,我不知道如何将其反向翻译为 Eloquent。 ORM 适用于简单查询,但当事情变得有点复杂时,我更喜欢回到 SQL。

【讨论】:

  • 惊人的答案!虽然,我更喜欢在 ORM 中完成它,但我想知道这个 SQL 的效率和运行时,必须检查它,我会等着看是否有人设法将它翻译成 ORM 风格,并会接受这个如果没有,请回答。谢谢乔阿诺洛!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多