web-dev-qa-db-ja.com

mysqlのループ外部キーを掛けた他のテーブルに参加する

私は2つのテーブルを持っています1つのノードとリレーションと2番目のストアが各ノードを購入します。私のコードは正常に機能しますが、ノードごとに複数の購入を合計すると、購入数を掛けた結果になります。

テーブルノード

+-------------+---------------+-------------+
| ancestor_id | descendant_id | path_length |
+-------------+---------------+-------------+
|           1 |             1 |           0 |
|           1 |             2 |           1 |
|           1 |             3 |           2 |
|           1 |             4 |           1 |
|           1 |             5 |           2 |
|           1 |             6 |           3 |
|           1 |             7 |           4 |
|           2 |             2 |           0 |
|           2 |             3 |           1 |
|           2 |             5 |           1 |
|           2 |             6 |           2 |
|           2 |             7 |           3 |
|           3 |             3 |           0 |
|           4 |             4 |           0 |
|           5 |             5 |           0 |
|           5 |             6 |           1 |
|           5 |             7 |           2 |
|           6 |             6 |           0 |
|           6 |             7 |           1 |
|           7 |             7 |           0 |
+-------------+---------------+-------------+

テーブル購入

 +-------------+---------------+-------------+
   |      userid |        amount |
   +-------------+---------------+-------------+
   |           2 |          1500 |
   |           7 |          2000 |
   +-------------+---------------+-------------+

mysqlコード

SELECT 

    DISTINCT users.descendant_id  ,
    SUM(CASE WHEN ances.ancestor_id = buys_ances.userid THEN 1 ELSE 0 END) level_compress  


    FROM webineh_prefix_nodes_paths as users 

    join webineh_user_buys as buys on (users.descendant_id = buys.userid  )

    join webineh_prefix_nodes_paths as ances on (users.descendant_id = ances.descendant_id )

    join webineh_user_buys as buys_ances on (buys_ances.userid = ances.ancestor_id )



    WHERE  users.ancestor_id = 1 

     and
    (SELECT SUM(g2.amount) as amount FROM webineh_user_buys g2 where  g2.userid = ances.ancestor_id     group by  g2.userid ) >= 1000  

     and
    (SELECT SUM(g1.amount) as amount FROM webineh_user_buys g1 where  g1.userid = users.descendant_id   group by  g1.userid ) >= 1000  


group by buys.userid ,ances.ancestor_id 

現在の購入データの結果

users.descendant_id   |  users.ancestor_id   |      level_compress

2                     |                      |         1
6                     |                      |         2

ancestor_id圧縮IDを表示する必要があります

2
Vahid Alvandi

掛け算される金額の問題は簡単に解決できます。計算を行う派生テーブルを使用する必要があります(group by)最初に、その(派生テーブル)を、階層構造を格納する他のテーブルに結合します。

使用する派生テーブル:

( SELECT userid,
         SUM(amount) AS sele_descendant_amount
  FROM webineh_user_buys 
  GROUP BY userid
  HAVING SUM(amount) >= 1000
) AS buys 

次に、それを他のテーブルに結合できます。また、2回参加する必要があります。これは、クエリの効率を低下させる可能性のあるもう1つの問題です。残念ながら、MySQLにはまだCTEがないため、派生テーブルコードを複製する必要があります。しかし、少なくともこのコードから始めることができます。

SQLfiddleでテスト済み:

SELECT
    buys_d.userid, 
    buys_d.sele_descendant_amount, 
    COUNT(*) AS level
FROM
    ( SELECT userid,
             SUM(amount) AS sele_descendant_amount
      FROM webineh_user_buys 
      GROUP BY userid
      HAVING SUM(amount) >= 1000
    ) AS buys_d 
  JOIN
    webineh_prefix_nodes_paths AS users 
      ON  users.descendant_id = buys_d.userid 
  JOIN
    ( SELECT userid,
             SUM(amount) AS sele_descendant_amount
      FROM webineh_user_buys 
      GROUP BY userid
      HAVING SUM(amount) >= 1000
    ) AS buys_a
      ON  users.ancestor_id = buys_a.userid 
GROUP BY
    buys_d.userid, buys_d.sele_descendant_amount ;
4
ypercubeᵀᴹ