のは、これらがあなたのテーブルです想像してみましょう:
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に戻ることを好みます。
あなたが試したことを分かち合うことができますか? – jmattheis
"orHhereHas"に沿って "whereHas"を使用してビルダーに "with"を追加しようとしましたが、確かに効率的な大量構文を構築します –