0

そのため、PHP で現在行われていることを 3 つの個別のクエリに置き換えるために、単一の MySQL クエリを作成しようとしています。ID と名前の 2 つの値のみを持つカテゴリのテーブルがあります。他に 2 つのテーブルがあり、それぞれが最初のテーブルの ID を参照する外部キーを持っています。Categories テーブルからすべての値のリストを取得するだけでなく、他の 2 つのテーブルで各値が参照される回数も取得する必要があります。それぞれに別のクエリを使用して、2 番目のテーブルのそれぞれから正確にカウントを取得できます。

SELECT nga_calevir_event_categories.*, COUNT(nga_calevir_events.event_id) AS event_total
FROM nga_calevir_event_categories
LEFT JOIN (nga_calevir_events)
ON nga_calevir_event_categories.id = nga_calevir_events.event_category
GROUP BY nga_calevir_event_categories.id;

SELECT nga_calevir_event_categories.*, COUNT(nga_usermeta.user_id) AS member_total
FROM nga_calevir_event_categories
LEFT JOIN (nga_usermeta)
ON (nga_usermeta.meta_value = nga_calevir_event_categories.id
AND nga_usermeta.meta_key = 'category_id')
GROUP BY nga_calevir_event_categories.id;

ただし、これらのクエリを結合しようとすると、両方のカウントで誤った結果が得られ始めます。結合されたクエリは次のとおりです。

SELECT nga_calevir_event_categories.*,
COUNT(nga_calevir_events.event_id) AS event_total,
COUNT(nga_usermeta.user_id) AS member_total
FROM nga_calevir_event_categories
LEFT JOIN (nga_calevir_events)
ON nga_calevir_event_categories.id = nga_calevir_events.event_category
LEFT JOIN (nga_usermeta)
ON (nga_usermeta.meta_value = nga_calevir_event_categories.id
AND nga_usermeta.meta_key = 'category_id')
GROUP BY nga_calevir_event_categories.id;

最初の行のカウントを 2 倍にしているようです。私はこれを数時間実験してきましたが、それを理解することはできません. 何か案は?これについてさらに情報が必要な場合はお知らせください。

4

1 に答える 1

1

結合は組み合わせであるため、これは機能しません。

SELECT nga_calevir_event_categories.*,
COUNT(nga_calevir_events.event_id) AS event_total,
COUNT(nga_usermeta.user_id) AS member_total


FROM nga_calevir_event_categories
LEFT JOIN (nga_calevir_events)
ON nga_calevir_event_categories.id = nga_calevir_events.event_category
-- The above is almost the same as an inner join, so long as every 
-- category has at least one event.

LEFT JOIN (nga_usermeta)
ON (nga_usermeta.meta_value = nga_calevir_event_categories.id
AND nga_usermeta.meta_key = 'category_id')
-- This is where you're going to get weird.  This is going to join 
-- every row already figured out- basically, a row for every event
-- with every usermeta that matches!


GROUP BY nga_calevir_event_categories.id;

これは実際には2つのクエリです。usermetaをカテゴリに結合するための正しい方法はありません(アプリケーションを誤解しない限り)。ただし、それを1つのSQLステートメントにまとめる方法があります。これを試して:

SELECT categories.*,
       coalesce(event_hits.hits, 0) + coalesce(meta_hits.hits, 0) as total_hits
FROM nga_calevir_event_categories as categories       

LEFT JOIN
(select event_category as catid, count(*) as hits
    FROM (nga_calevir_events)
    group by event_category
) as event_hits ON event_hits.catid = categories.id

LEFT JOIN (
   select meta_value as catid, count(*) as hits
   FROM nga_usermeta
   WHERE meta_key = 'category_id'
   group by meta_value
) as meta_hits ON meta_hits.catid = categories.id

これは、2つの内部選択を使用して2つのテーブルのそれぞれに使用されるカテゴリIDのカウントを取得し、それらの内部選択を実際のカテゴリに結合して、それぞれが返したカウントを合計します。COALESCEを使用して、テーブルの1つで使用がなかった場合、0が想定されるようにします。

お役に立てれば!

于 2012-06-14T22:47:17.957 に答える