0

これは、私がやろうとしていることはかなり複雑であるため、説明するには少し高度かもしれません (少なくとも私にとっては)。

私は現在、PHP と MySQL で個人用の映画データベースを構築していますが、MySQL の部分が私を殺しています。現在のセットアップは次のようになります。

名前、説明、および値を含むメインの映画データベースがあり、オプションは 1 つ (年、年齢制限、メディアの種類 (DVD、Blu-Ray など) など) です。

言語、字幕、オーディオ形式などの追加のテーブルがあり、すべて 2 つの列があります。1 つは映画の ID 用で、もう 1 つはインデックス (言語 ID など) に一致します。これらはメイン テーブルと一緒に結合され、1 つのフィールドに連結されることになっています。

私の言語テーブルの例:

movid | langid
--------------
1     | 2
1     | 4
2     | 4
3     | 5     

最適には、次のようなものが必要です。

| ID | name    | description | year | subtitles | languages | audio |
--------------------------------------------------------------------
| 1  | One     | Bla bla     | 2010 | 2,3,5,6,7 | 3,6,22,6  | 10,5  |
| 2  | Another | foo bar     | 2008 | 6,33,5,27 | 10,4,2,3  | 8,15  |

字幕と言語を PHP 配列に展開できます。その部分は、特定のサブ ID またはラン ID を検索する必要がある部分まで、GROUP_CONCAT を使用して実際に問題なく動作しています。これは私がこれまで使用してきたクエリです。すべてのテーブル情報を書き出していませんが、アイデアが得られることを願っています。

SET SESSION group_concat_max_len = 512;

SELECT
movie.id,
movie.name,
movie.origname,
movie.`year`,
movie.`type`,
movie.duration,
movie.age,
GROUP_CONCAT(DISTINCT movie_language.langid ORDER BY langid) AS lang,
GROUP_CONCAT(DISTINCT movie_subtitles.subid ORDER BY subid) AS subtitles

FROM `movie`

LEFT JOIN `movie_audio` ON `movie`.`id`=`movie_audio`.`movid` 
LEFT JOIN `movie_company` ON `movie`.`id`=`movie_company`.`movid` 
LEFT JOIN `movie_genre` ON `movie`.`id`=`movie_genre`.`movid` 
LEFT JOIN `movie_language` ON `movie`.`id`=`movie_language`.`movid` 
LEFT JOIN `movie_subtitles` ON `movie`.`id`=`movie_subtitles`.`movid` 

GROUP BY movie.id

私は group_concat_max_len を使用して BLOB を取得しないようにしています。これまでのところ、結合されたテーブルのうちの 2 つだけを group_concatting しようとしました (残りは後で追加します)。

これはまさに私が望むものを返しますが、結合されたテーブルごとに WHERE 句を 1 つしか持つことができません。そうしないと、0 行が返されます。繰り返しますが、1 つだけを検索すると、検索された番号/ID のみが GROUP_CONCAT'ted フィールドに返されます。

次に、IN() 関数を使用して修正しました。少なくとも私はそう思った。しかし、問題は、私が OR 検索と呼んでいるものでしか機能しないことです。追加:

WHERE movie_subtitles.subid IN ()

字幕テーブルにない番号でも、一致する番号のみで行を返します。半分の検索ではこれで問題ありませんが、AND のような方法で検索する方法も必要です。

完全に再構築する必要があるのか​​、それともまったく別のクエリが必要なのかはわかりませんが、何らかの支援やヒントがあれば幸いです。

HAVING オプションも調べたことがありますが、私が理解している限りでは、私のクエリでは効果がありません。

ちなみに、これが不可能な場合は、結合されたテーブルを廃棄して、メインのムービー テーブルで簡単に検索できるフィールドに置き換えることを検討しました (この「構文」を使用するように: '#2##4#' とその後LIKE '%#2#%' AND '%#4#%' を使用して結果を照合するか、最後の手段として PHP を使用してそれを整理します (それを行うよりもむしろ死にたいです)。上記の解決策を修正して使用できる場合)。

私の頭痛を和らげてくれてありがとう!

4

1 に答える 1

0

選択したサブクエリを実行すると、句を簡単に使用できます。

お気に入り:

select *
   from (`your big query above`) as t
where subtitles regexp `your ids you want`
and lang regexp `your ids you want`

まあ、あなたのIDは文字列に変換されるので完璧ではありません(postgresには配列があるので、トップレベルから適切な検索を行うことができます.)しかし、正規表現でIDを検索したいとは思いません.

その場合は、最終レベルまで ID を連結しない方がよいでしょう。したがって、3 レベルのクエリが必要です。

select 
  stuff, ...
  group_concats
from
(
    select *
       from (`your big query above but without the group_concat`) as inner
    conditions ...

) as outer

編集

これを試して:

SELECT
id,
name,
origname,
`year`,
`type`,
duration,
age,

-- at this point we have the right rows we are just
-- grouping lang and subtitles
GROUP_CONCAT(DISTINCT langid ORDER BY langid) AS lang,
GROUP_CONCAT(DISTINCT subid ORDER BY subid) AS subtitles

from
(

    (
        SELECT
            movie.id,
            movie.name,
            movie.origname,
            movie.`year`,
            movie.`type`,
            movie.duration,
            movie.age,
            langid,
            subid


            FROM `movie`

            LEFT JOIN `movie_audio` ON `movie`.`id`=`movie_audio`.`movid`
            LEFT JOIN `movie_company` ON `movie`.`id`=`movie_company`.`movid`
            LEFT JOIN `movie_genre` ON `movie`.`id`=`movie_genre`.`movid`
            LEFT JOIN `movie_language` ON `movie`.`id`=`movie_language`.`movid`
            LEFT JOIN `movie_subtitles` ON `movie`.`id`=`movie_subtitles`.`movid`


            -- each row will have a different langid and different subid
            GROUP BY
                movie.id, langid, subid

    ) as inner

    -- you should be able to do any complex condition as this point
    where
        (langid = 1 or langid = 2)
        and (subid = 2 or subid = 3)

) as outer
于 2010-11-20T23:33:12.640 に答える