1

私は映画、俳優、監督のためのテーブルを備えた映画データベースを持っています。各ムービーは、ムービーテーブルの1行を占めます。ほとんどすべてのクエリでは、LIMIT 50、オフセット0のクエリが約4本の映画の完全なデータを返すように、他のテーブルへの結合が必要です。以下はサンプルクエリです。これを変更して、正確に10本の映画のデータを確実に取得するにはどうすればよいですか?

SELECT movie.id, movie.title, star.name, star.name_url, dir.name, 
       dir.name_url, genre.name, genre.name_url 
FROM movie 
        LEFT JOIN actor 
             ON (movie.id = actor.movie_id) 
        LEFT JOIN person AS star 
             ON (actor.person_id = star.id) 
        LEFT JOIN director 
             ON (movie.id = director.movie_id) 
        LEFT JOIN person AS dir 
             ON (director.person_id = dir.id) 
        LEFT JOIN genre_classification 
             ON (movie.id = genre_classification.movie_id) 
        LEFT JOIN genre 
             ON (genre_classification.genre_id = genre.id)
WHERE (movie.id > 0) 
ORDER BY movie.id 
LIMIT 50 OFFSET 0;

私はおそらく問題ではないPostgresSQLを使用しています。

4

3 に答える 3

3

そこに行きます(テストされていません):

SELECT movie.id, movie.title, star.name, star.name_url, dir.name, 
       dir.name_url, genre.name, genre.name_url 
FROM 
        (SELECT * FROM movie WHERE movie.id > 0 ORDER BY movie.id LIMIT 10) movie
        LEFT JOIN actor 
             ON (movie.id = actor.movie_id) 
        LEFT JOIN person AS star 
             ON (actor.person_id = star.id) 
        LEFT JOIN director 
             ON (movie.id = director.movie_id) 
        LEFT JOIN person AS dir 
             ON (director.person_id = dir.id) 
        LEFT JOIN genre_classification 
             ON (movie.id = genre_classification.movie_id) 
        LEFT JOIN genre 
             ON (genre_classification.genre_id = genre.id)

編集:すべての条件を副選択に入れることにより、ソーステーブルのどのデータをmovieJOINに使用するかを制御できません。パフォーマンスに関しては、これもはるかに高速であるはずです。

于 2012-08-30T15:01:54.950 に答える
1

参考までに、以下の方が賢いです。使用せずSELECT *、パフォーマンスを最適化します(問題がない場合でも):

SELECT movie.id, movie.title, star.name, star.name_url, dir.name, 
       dir.name_url, genre.name, genre.name_url 
FROM movie 
        LEFT JOIN actor          ON (movie.id = actor.movie_id) 
        LEFT JOIN person AS star ON (actor.person_id = star.id) 
        LEFT JOIN director       ON (movie.id = director.movie_id) 
        LEFT JOIN person AS dir  ON (director.person_id = dir.id) 
        LEFT JOIN genre_classification ON (movie.id = genre_classification.movie_id) 
        LEFT JOIN genre          ON (genre_classification.genre_id = genre.id)
        JOIN (
            SELECT id
            FROM movie
            WHERE (id > 0) 
            ORDER BY id
            LIMIT 10
        ) AS sel ON (sel.id=movie.id)
ORDER BY movie.id;
于 2012-08-30T15:46:52.133 に答える
0

まだテストされていません。tdkで与えられた答えよりもパフォーマンスは劣りますが、読みやすく、副選択はWITHステートメントを使用して記述できます。

WITH 
  sub_movie AS (
    SELECT * FROM movie WHERE movie.id > 0 ORDER BY movie.id LIMIT 10
   )
SELECT
  sm.id,
  sm.title,
  star.name,
  star.name_url,
  dir.name,
  dir.name_url,
  genre.name,
  genre.name_url
FROM
  sub_movie sm
    LEFT JOIN actor 
         ON (movie.id = actor.movie_id) 
    LEFT JOIN person AS star 
         ON (actor.person_id = star.id) 
    LEFT JOIN director 
         ON (movie.id = director.movie_id) 
    LEFT JOIN person AS dir 
         ON (director.person_id = dir.id) 
    LEFT JOIN genre_classification 
         ON (movie.id = genre_classification.movie_id) 
    LEFT JOIN genre 
         ON (genre_classification.genre_id = genre.id)

PK列を呼び出さずに、代わりに次のようなスマート結合構文を使用できるようにすることをお勧めしますidmy_table_id

    LEFT JOIN director USING (director_id)

幸運を。

于 2012-08-30T15:54:03.220 に答える