私は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を表示する必要があります
掛け算される金額の問題は簡単に解決できます。計算を行う派生テーブルを使用する必要があります(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 ;