サー、質問の要件はまだ不明です。
例を使用して私の混乱を説明します。
簡単なデモをご覧ください: http://sqlfiddle.com/#!2/19f52c/6
このデモには、単純化された (わかりやすくするための) データベース構造とクエリが含まれています。
質問のクエリ (デモの最初のクエリ) は、次の結果を返します。
SELECT action.actionid
FROM ACTION
INNER JOIN EVENT
ON action.eventid = event.eventid
LEFT JOIN
(SELECT
COUNT(1),
action.eventid
FROM
ACTION
WHERE (action.typeid = '2')
GROUP BY action.eventid) AS act
ON act.eventid = event.eventid
WHERE -- actiondate2 BETWEEN 20130601 AND 20131031 AND
event.siteid = 1
AND action.typeid = 1
;
+ ------------- +
| actionid |
+ ------------- +
| 1 |
| 3 |
| 5 |
+ ------------- +
ただし、上記のクエリでは、エイリアスを使用したサブクエリACT
は単に...役に立たない.
クエリはこのサブクエリを実行し (時間とサーバー リソースを消費します)、その結果を無視して破棄します。
上記のクエリは、以下のクエリ (デモの 2 番目のクエリ) と同等です。サブクエリを使用せずに、質問のクエリと同じ結果を返します (時間とリソースを節約するため、パフォーマンスが大幅に向上します)。
SELECT action.actionid
FROM
ACTION
INNER JOIN EVENT
ON action.eventid = event.eventid
WHERE -- actiondate2 BETWEEN 20130601 AND 20131031 AND
event.siteid = 1
AND action.typeid = 1
;
+ ------------- +
| actionid |
+ ------------- +
| 1 |
| 3 |
| 5 |
+ ------------- +
あなたの意図があなたの質問に表示されるクエリを最適化することである場合は、上記のクエリを使用してください。これがあなたの質問に対する答えです。
ただし、期待される結果についてのコメントを見ると、質問のクエリはおそらく間違っているようです。期待される結果が得られません。
まあ、しかし、クエリが何を与えるべきかはまだ不明です? 多くの可能性がありますが、以下にいくつかを示します。
action.actionid
すべてをでリストする必要があるtypeid = 1
が、そのようなレコードのみをリストする必要がある場合は、同じおよび... を持つレコードが存在する場合は、以下のクエリ (デモの 3 番目のクエリ) を使用します。eventid
typeid = 2
SELECT a.actionid
FROM
ACTION a
INNER JOIN EVENT e
ON a.eventid = e.eventid
WHERE -- actiondate2 BETWEEN 20130601 AND 20131031 AND
EXISTS ( SELECT 1 FROM action a1
WHERE a1.eventid = a.eventid
AND a1.typeid = 2
)
AND e.siteid = 1
AND a.typeid = 1
;
+ ------------- +
| actionid |
+ ------------- +
| 1 |
| 3 |
+ ------------- +
このクエリではEXISTS
、代わりに演算子を使用していますCOUNT()
- 同じレコードが存在するという情報が必要な場合、それらすべてをカウントする必要はありません! count はすべてのレコードを読み取る必要があり、EXISTS
条件を満たす最初のレコードが見つかった場合はテーブルの読み取りを停止します。したがってEXISTS
、通常は よりも高速ですCOUNT()
。
すべてaction.actionid
をtypeid = 1
で一覧表示し、対応するレコードが存在する情報も表示する必要がある場合typeid = 2
は、以下のクエリ (デモの 4 番目のクエリ) を使用します。
SELECT
a.actionid ,
CASE WHEN EXISTS ( SELECT 1 FROM action a1
WHERE a1.eventid = a.eventid
AND a1.typeid = 2
)
THEN 'typeid=2 EXISTS'
ELSE 'typeid=2 DOESN''T EXIST'
END typeid2_exist
FROM
ACTION a
INNER JOIN EVENT e
ON a.eventid = e.eventid
WHERE -- actiondate2 BETWEEN 20130601 AND 20131031 AND
e.siteid = 1
AND a.typeid = 1
;
+ ------------- + ---------------------- +
| actionid | typeid2_exist |
+ ------------- + ---------------------- +
| 1 | typeid=2 EXISTS |
| 3 | typeid=2 EXISTS |
| 5 | typeid=2 DOESN'T EXIST |
+ ------------- + ---------------------- +
ただし、対応するレコードを - でカウントする必要がある場合はtypeid = 2
、次のクエリが役立ちます (デモの 5 番目のクエリ)。
SELECT
a.actionid ,
( SELECT count(*) FROM action a1
WHERE a1.eventid = a.eventid
AND a1.typeid = 2
) typeid2_count
FROM
ACTION a
INNER JOIN EVENT e
ON a.eventid = e.eventid
WHERE -- actiondate2 BETWEEN 20130601 AND 20131031 AND
e.siteid = 1
AND a.typeid = 1
;
+ ------------- + ------------------ +
| actionid | typeid2_count |
+ ------------- + ------------------ +
| 1 | 1 |
| 3 | 1 |
| 5 | 0 |
+ ------------- + ------------------ +
上記のクエリのいずれも要件を満たしていない場合は、(デモのサンプル データに基づいて) クエリが返す必要がある結果を示してください。これは、このフォーラムの誰かが要件をすべて満たす適切なクエリを作成するのに役立ちます。
次に、すべての期待を満たす適切なクエリを認識したら、そのパフォーマンスの最適化を開始できます。