0

7つのテーブルから組み合わせたselectステートメントがあります

SELECT * (//instead of * i put in my code the proper columns i need from the selected tabls)
FROM 
ev_events_eve
LEFT JOIN ev_events_multilang_evmulti ON ev_events_multilang_evmulti.event_evmulti = ev_events_eve.id_eve
LEFT JOIN ev_schedule_sch ON ev_schedule_sch.event_id_sch = ev_events_eve.id_eve
LEFT JOIN ev_events_type_et ON ev_schedule_sch.event_type_id_sch = ev_events_type_et.id_et
LEFT JOIN ev_events_type_multilang_etmulti ON ev_events_type_multilang_etmulti.idevent_type_etmulti = ev_events_type_et.id_et
LEFT JOIN ev_schedule_multilang_schmulti ON ev_schedule_multilang_schmulti.id_schedule_schmulti = ev_schedule_sch.id_sch
LEFT JOIN ev_timetable_tt ON ev_timetable_tt.schedule_id_tt = ev_schedule_sch.id_sch AND ev_timetable_tt.event_id_tt = ev_events_eve.id_eve
WHERE (ev_events_eve.active_eve = 1 AND ev_schedule_multilang_schmulti.iso_code_lang_schmulti = '{$current_language}' AND ev_schedule_sch.active_sch = 1) AND
ev_timetable_tt.end_date_tt > CURDATE() OR (ev_timetable_tt.weekday_tt = DAYNAME(CURDATE()) AND ev_timetable_tt.end_date_tt > CURDATE()) OR ev_timetable_tt.specific_date_tt > CURDATE()
ORDER BY ev_timetable_tt.start_date_tt ASC LIMIT 3

このステートメントがwhere句を無視しているという問題、サンプルsqlステートメントを作成するために使用するmysqlを使用するたびに、通常の左結合または内部結合を持つ2つまたは3つのテーブルで構成されているため、この問題について話し合う必要があります。私のコードで言及されていないことをさらに調べてください、しかし私は上記のコードが私と一緒にこの問題を処理するのに十分ではないことを知っています、しかし私はそれを私と話し合うことができる誰かが必要です

次の情報で質問を更新しました

主なビジネスルール:

  • プロジェクトは多言語のウェブサイトのためのものです

  • テーブルは次のとおりです。
    • ev_events_eve(ID、ロゴ、スローガン、イベント全体の開始日と終了日などのイベントエンティティ)
      • ev_events_multilang_evmulti(名前(en、fr、grなど)、説明などのメインイベントテーブルの多言語テーブル…など)
      • ev_schedule_sch(ID、イベントテーブルへの外部キーなどのスケジュールエンティティ)
      • ev_schedule_multilang_schmulti(メインスケジュールテーブルの多言語テーブル)
      • ev_timetable_tt(ev_schedule_schテーブルに関連する開始日時と終了日時を保存します)

  • すべてのテーブルは2つのテーブルに複製され、1つはエンティティを格納し、もう1つは多言語データを格納します。

  • テーブル間の関係
    • メインテーブルはev_events_eveです
    • ev_events_multilang_evmulti外部キーを介してメインテーブルに関連付けられています
    • ev_schedule_sch related外部キーを介してメインテーブルに
    • ev_schedule_multilang_schmultiev_schedule_sch外部キーを介してテーブルに関連
    • ev_timetable_ttev_schedule_sch外部キーを介して関連しています

イベントテーブルから着信3行を取得するステートメントを作成する必要があります(すべてのフィールドの完全なスキーマがないため、最新の3行を取得する必要があるとしましょう。後で、WHERE句で説明します。 ))に加えて、この3行は、イベントテーブルのすべての行に関連するスケジュールテーブルから6行も取得します。したがって、推定結果は次のようになります。4つのイベントがあると仮定します。

  • 1番目は呼ばれます:event#1
    • このイベントには、スケジュール関連のテーブルに3つの行があります(したがって
      、これらの行をすべて取得します)


  • 2番目は呼ばれます:event#2
    • これには、スケジュール関連のテーブルに11行あります(それらから6行のみを取得します)

  • 3番目は呼ばれます:event#3
    • このイベントには、スケジュール関連のテーブルに関連する行がありません

  • 4番目は呼ばれます:event#4
    • このイベントには、スケジュール関連のテーブルに関連する行が1つだけあります

上記のように、スケジュール内の最初の3つのイベントと関連するイベントを取得する必要があるのは私だけです

4

3 に答える 3

2

問題はクエリのOR部分にあると推測しています。クエリのこの部分を変更しました:

AND ( 
ev_timetable_tt.end_date_tt > CURDATE() 
OR (ev_timetable_tt.weekday_tt = DAYNAME(CURDATE()) AND ev_timetable_tt.end_date_tt > CURDATE()) 
OR ev_timetable_tt.specific_date_tt > CURDATE()
)

おそらくあなたはこれをしたいでしょう:(読みやすくするためにエイリアスを付けました)

SELECT * 
FROM ev_events_eve e
LEFT JOIN ev_events_multilang_evmulti eml ON eml.event_evmulti = e.id_eve
LEFT JOIN ev_schedule_sch es ON es.event_id_sch = e.id_eve
LEFT JOIN ev_events_type_et et ON es.event_type_id_sch = et.id_et
LEFT JOIN ev_events_type_multilang_etmulti emel ON emel.idevent_type_etmulti = et.id_et
LEFT JOIN ev_schedule_multilang_schmulti ems ON ems.id_schedule_schmulti = es.id_sch
LEFT JOIN ev_timetable_tt ett ON ett.schedule_id_tt = es.id_sch AND ett.event_id_tt = e.id_eve
WHERE (e.active_eve = 1 AND ems.iso_code_lang_schmulti = '{$current_language}' AND es.active_sch = 1) 
AND 
(
    ett.end_date_tt > CURDATE() 
OR (ett.weekday_tt = DAYNAME(CURDATE()) AND ett.end_date_tt > CURDATE()) 
OR ett.specific_date_tt > CURDATE()
)
ORDER BY ett.start_date_tt ASC
LIMIT 3

構文で(テーブルエイリアスなしで)好む場合:

SELECT * (//instead of * i put in my code the proper columns i need from the selected tabls)
FROM 
ev_events_eve
LEFT JOIN ev_events_multilang_evmulti ON ev_events_multilang_evmulti.event_evmulti = ev_events_eve.id_eve
LEFT JOIN ev_schedule_sch ON ev_schedule_sch.event_id_sch = ev_events_eve.id_eve
LEFT JOIN ev_events_type_et ON ev_schedule_sch.event_type_id_sch = ev_events_type_et.id_et
LEFT JOIN ev_events_type_multilang_etmulti ON ev_events_type_multilang_etmulti.idevent_type_etmulti = ev_events_type_et.id_et
LEFT JOIN ev_schedule_multilang_schmulti ON ev_schedule_multilang_schmulti.id_schedule_schmulti = ev_schedule_sch.id_sch
LEFT JOIN ev_timetable_tt ON ev_timetable_tt.schedule_id_tt = ev_schedule_sch.id_sch AND ev_timetable_tt.event_id_tt = ev_events_eve.id_eve
WHERE (ev_events_eve.active_eve = 1 AND ev_schedule_multilang_schmulti.iso_code_lang_schmulti = '{$current_language}' AND ev_schedule_sch.active_sch = 1) 
AND ( 
ev_timetable_tt.end_date_tt > CURDATE() 
OR (ev_timetable_tt.weekday_tt = DAYNAME(CURDATE()) AND ev_timetable_tt.end_date_tt > CURDATE()) 
OR ev_timetable_tt.specific_date_tt > CURDATE()
)
ORDER BY ev_timetable_tt.start_date_tt ASC LIMIT 3
于 2012-04-22T12:27:00.127 に答える
0

まず、where句の日付基準をラップしてすべてをカプセル化する必要があると私も信じています。そうでない場合は、最初の部分を適用し、最初の「OR」が修飾されるとすぐに完全に無視します。次。左側のレコードが修飾されている限り、右側のテーブルのレコードではオプションのみであることを意味する多くの LEFT JOIN があります。ただし、右側のテーブルに対して WHERE 句に基準を追加すると、「LEFT」修飾がスローされます。その基準を where 句ではなく LEFT JOIN 条件に移動する必要があります (私が調整したように)。

元のクエリは、エイリアスを使用し、日付基準の括弧を修正して、誤った結果が得られないようにわずかにクリーンアップしましたが、WHERE 句を介して暗黙的に示され、NORMAL INNER 結合に変換されます。

SELECT *
   FROM 
      ev_events_eve EE

         LEFT JOIN ev_events_multilang_evmulti ELANG 
            ON EE.id_eve = ELANG.event_evmulti

         LEFT JOIN ev_schedule_sch SCHED 
            ON EE.id_eve = SCHED.event_id_sch

            LEFT JOIN ev_events_type_et ETYPE
               ON SCHED.event_type_id_sch = ETYPE.id_et

               LEFT JOIN ev_events_type_multilang_etmulti ETMLANG 
                  ON ETYPE.id_et = ETMLANG.idevent_type_etmulti

            LEFT JOIN ev_schedule_multilang_schmulti SMS 
               ON SCHED.id_sch = SMS.id_schedule_schmulti

            LEFT JOIN ev_timetable_tt TIMET 
               ON SCHED.id_sch  = TIMET.schedule_id_tt
              AND EE.id_eve = TIMET.event_id_tt

   WHERE 
          (   EE.active_eve = 1 
          AND SMS.iso_code_lang_schmulti = '{$current_language}' 
          AND SCHED.active_sch = 1 ) 
      AND (      TIMET.end_date_tt > CURDATE() 
            OR (    TIMET.weekday_tt = DAYNAME(CURDATE()) 
                AND TIMET.end_date_tt > CURDATE()) 
            OR TIMET.specific_date_tt > CURDATE() )
   ORDER BY 
      TIMET.start_date_tt ASC LIMIT 3

そして、それぞれの LEFT JOIN を保持するように調整されたクエリを次に示します。基準が配置されている場所の違いに注意してください。

SELECT *
   FROM 
      ev_events_eve EE

         LEFT JOIN ev_events_multilang_evmulti ELANG 
            ON EE.id_eve = ELANG.event_evmulti

         LEFT JOIN ev_schedule_sch SCHED 
            ON EE.id_eve = SCHED.event_id_sch
           AND SCHED.active_sch = 1

            LEFT JOIN ev_events_type_et ETYPE
               ON SCHED.event_type_id_sch = ETYPE.id_et

               LEFT JOIN ev_events_type_multilang_etmulti ETMLANG 
                  ON ETYPE.id_et = ETMLANG.idevent_type_etmulti

            LEFT JOIN ev_schedule_multilang_schmulti SMS 
               ON SCHED.id_sch = SMS.id_schedule_schmulti
              AND SMS.iso_code_lang_schmulti = '{$current_language}' 

            LEFT JOIN ev_timetable_tt TIMET 
               ON SCHED.id_sch  = TIMET.schedule_id_tt
              AND EE.id_eve = TIMET.event_id_tt
              AND (      TIMET.end_date_tt > CURDATE() 
                    OR (    TIMET.weekday_tt = DAYNAME( CURDATE() ) 
                        AND TIMET.end_date_tt > CURDATE() ) 
                    OR TIMET.specific_date_tt > CURDATE()    )
   WHERE 
      EE.active_eve = 1 
   ORDER BY 
      TIMET.start_date_tt ASC LIMIT 3

最後に 1 つ。あなたのORDER BYは、「ev_TimeTable_tt」(TIMETとしてエイリアス化された)テーブルを参照しています。これは、EXPLICITLYとの一致のみがこのテーブルで見つかることを常に期待していることを意味します。その場合、これは実際には LEFT JOIN ではなく INNER JOIN である必要があります。

「EV_TIMETABLE_TT」テーブルに到達するには、スケジュール テーブルから検索する必要があるため、これも INNER JOIN 要件であると予想されます。

したがって、LEFT 結合と INNER 結合の明確化により、おそらくこれらの組み合わせに調整する必要があります。あなたのデータがわからないので、これ以上指示することはできません。

于 2012-04-22T13:06:43.743 に答える
0

s をed であるテーブルで非値を必要LEFT JOINとする条件と組み合わせて使用​​すると、 a を使用する目的そのものが無効になります。条件で値を指定するか、条件を のの一部にする必要があります。WHERENULLLEFT JOINLEFT JOINWHERE[whatever] OR NULLWHEREONJOIN

例えば:

... WHERE ... (ev_schedule_sch.active_sch = 1 OR ev_schedule_sch.active_sch IS NULL) ...

または

... LEFT JOIN ev_schedule_sch ON ev_schedule_sch.event_id_sch = ev_events_eve.id_eve AND ev_schedule_sch.active_sch = 1 ...
于 2012-04-22T12:38:40.583 に答える