2016-07-21 13 views
0

ビルドする必要があるSQLクエリはかなり複雑です。私を許して、私はSQLを持つ魔法の魔法使いではありません。SQLクエリの複雑なグループ化

はここに私の二つのテーブル(大幅に単純化された)です:

にtableA

id request_id page_views step 
----------------------------------- 
1 1   0   0 
2 1   0   1 
3 1   0   2 
4 1   0   3 
5 2   0   0 
6 2   0   1 
7 2   1   2 
8 3   0   0 
9 3   0   1 
10 4   0   0 
11 4   0   1 
12 4   0   2 

TABLEB

id name   phone  
------------------------------ 
1 John Deere 111-222-3333 
2 Sally Sue 333-222-1111 
3 Jacob Clark 434-343-4343 
4 Alex Smith 222-112-2112 

まず、tableA.request_id = tableB.idはにつながるためのテーブルに参加することが必要です:

id request_id page_views step name   phone 
---------------------------------------------------------------- 
1 1   0   0  John Deere 111-222-3333 
2 1   0   1  John Deere 111-222-3333 
3 1   0   2  John Deere 111-222-3333 
4 1   0   3  John Deere 111-222-3333 
5 2   0   0  Sally Sue 333-222-1111 
6 2   0   1  Sally Sue 333-222-1111 
7 2   1   2  Sally Sue 333-222-1111 
8 3   0   0  Jacob Clark 434-343-4343 
9 3   0   1  Jacob Clark 434-343-4343 
10 4   0   0  Alex Smith 222-112-2112 
11 4   0   1  Alex Smith 222-112-2112 
12 4   0   2  Alex Smith 222-112-2112 

そのテーブルから、以下の条件に一致するグループが返されるようにします。グループごとに、私は同じものを持つ行のグループを意味するrequest_id。ここでは条件があります:グループ内の行の

  1. 、どれもグループ内の行の0
  2. よりpage_views大きなを持っていない、のいずれかの場合はどれも2

よりstep大きなを持っていません上記の2つの条件は失敗し、グループ全体が返されません。

id request_id page_views step name   phone 
---------------------------------------------------------------- 
8 3   0   0  Jacob Clark 434-343-434 
9 3   0   1  Jacob Clark 434-343-434 
10 4   0   0  Alex Smith 222-112-2112 
11 4   0   1  Alex Smith 222-112-2112 
12 4   0   2  Alex Smith 222-112-2112 

「3」グループ(またはヤコブ・クラーク)はpage_viewsが0よりも大きい任意の行を持っていなかった、と行のどれもが持つstep 2より大きいと同じ持っていません。だからここに返されるべきものです"4"グループ(またはAlex Smith)。

それが問題です。私はすべてを処理する単一のSQLクエリが必要です。最初の結合はサブクエリで問題ありません。

SELECT sub.* 
FROM (
    SELECT tableA.*, tableB.name, tableB.phone 
    FROM `tableA`, `tableB` 
    WHERE tableA.`request_id` = tableB.id 
) sub 

その後、私はあまりよく分かりません。

ご協力いただければ幸いです。

+0

'join'節は、あなたが望むように複雑/簡単にすることができます。 'join 1'は完全に有効で、単純にすべてのレコードに参加します。ブール値true(返されたレコードを結合)またはfalse(レコードを除外)を返す結合節へと変わります。表現が何であるかは、あなた次第です。 –

答えて

2

を:

SELECT a.*, b.name, b.phone 
FROM (
    SELECT request_id 
    FROM tableA 
    GROUP BY request_id 
    HAVING MAX(page_views) <= 0 AND MAX(step) <= 2 
) AS sumQ 
INNER JOIN tableA AS a ON sumQ.request_id = a.request_id 
INNER JOIN tableB AS b ON a.request_id = b.id 
; 

か、あるいは:私の経験で

SELECT a.*, b.name, b.phone 
FROM tableA AS a 
INNER JOIN tableB AS b ON a.request_id = b.id 
WHERE a.request_id IN (
    SELECT request_id 
    FROM tableA 
    GROUP BY request_id 
    HAVING MAX(page_views) <= 0 AND MAX(step) <= 2 
) 
; 

、最初のバージョンは通常より高速です。

+0

私は最初のものを試しました、それは、ありがとう! –

1

あなたはWHERE NOT EXISTSでこれを行うことができます:あなたは、サブクエリで別々に(REQUEST_IDで)最大ビューとステップを計算し、その後、十分に小さい最大値でREQUEST_ID年代を使用する必要が

Select A.id, A.request_id, A.page_views, A.step, 
     B.name, B.phone 
From TableA A 
Join TableB B On A.request_id = B.Id 
Where Not Exists 
(
    Select * 
    From TableA A2 
    Where A2.request_Id = A.request_id 
    And  (A2.page_views > 0 Or A2.step > 2) 
)