2017-07-30 14 views
0

に関連した動画を検索:雄弁ORM PHPは属性を持つ私は、次の表(およびモデル)を抱えているコメントやレビュー

Comments: 
- id 
- movie_id 
- date 

Reviews: 
- id 
- movie_id 
- date 

Movies: 
- id 

雄弁ORM &スリム3の枠組みでのPostgreSQLを使用しました。

注:持って多くのコメントや映画のレビューが、唯一の最後のレビュー(BIGGEST ID)がある場合もありますが、興味深い..です

作品: は、私はすべてを取得しようとしているコメントOR \ ANDその日の場所>(今 - 1日)。

トライが加入するとSQLでそれを書く、しかし..私は機能を読み取るために、より高度かつシンプルな雄弁の一部を使用することができることを考え出し しかし、これまでのところ、すべてのオプションで溺死し、できませんでした使用する正しい方法を見つけてください。 できるだけ効率的で明るくするためのヘルプがありますか?

ありがとうございます! Itay。

+0

あなたが試したことを分かち合うことができますか? – jmattheis

+0

"orHhereHas"に沿って "whereHas"を使用してビルダーに "with"を追加しようとしましたが、確かに効率的な大量構文を構築します –

答えて

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 ; 
 
movie_id | movie       | review_id | comment_id 
-------: | :---------------------------- | --------: | ---------: 
     2 | Start Trek: The Wrath of Khan |  null |   2 
     4 | The 39 steps     |  null |  null 
     1 | 2001 A Space Odissey   |  null |   1 
     3 | Start Trek Beyond    |   1 |  null 
前のクエリから

は、我々がレビューとコメント残りのデータを取得するために戻ってリンクされています

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 ; 

結果は次のとおりです。

 
movie_id | movie       | review_id | review_date | review                 | comment_id | comment_date | comment    
-------: | :---------------------------- | --------: | :---------- | :----------------------------------------------------------------------- | ---------: | :----------- | :------------------ 
     1 | 2001 A Space Odissey   |  null | null  | null                  |   1 | 2017-07-30 | Best film ever  
     2 | Start Trek: The Wrath of Khan |  null | null  | null                  |   2 | 2017-07-31 | Not as good as 2001 
     3 | Start Trek Beyond    |   1 | 2017-07-30 | Not the best Start Trek film ever, however, the best CGI imaginable, ... |  null | null   | null    

あなたはdbfiddle here

でこのすべてをテストすることができます

注:正直なところ、これをEloquentに逆翻訳する方法はわかりません。 ORMは単純なクエリには適していますが、状況が少し複雑になると、私はSQLに戻ることを好みます。

+0

驚くべき答え!私はORMでそれを達成するために優先しますが、私はこのSQLの効率的な機能と実行時間をチェックする必要があります 誰かがそれをORMスタイルに変換することができるかどうかを確認して受け入れますこの答えがなければ。 ありがとうJoanolo! –

関連する問題