这里有一些东西可以尝试(但未经测试)。
它展示了可用于在一个查询中处理多种模式的方法。
仅适用于 MySQL 5.7+ 并仅计算发现的每个基因模式。
如果您想要每个团队的计数,请调整 GROUP BY 和 SELECT list。
SELECT p.pattern
, COUNT(*) AS n
FROM DP.team JOIN DP.users ON DP.team.user_id = DP.users.id
JOIN (
SELECT '%,100002,%' AS pattern UNION ALL
SELECT '%,100005,%'
) AS p
ON CONCAT('%,', DP.team.gene_chain, ',%') LIKE p.pattern
GROUP BY p.pattern
ORDER BY p.pattern
;
我们真的不需要为此与用户一起加入:
SELECT p.pattern
, COUNT(*) AS n
FROM DP.team
JOIN (
SELECT '%,100002,%' AS pattern UNION ALL
SELECT '%,100005,%'
) AS p
ON CONCAT('%,', DP.team.gene_chain, ',%') LIKE p.pattern
GROUP BY p.pattern
ORDER BY p.pattern
;
结果:
+------------+---+
| pattern | n |
+------------+---+
| %,100002,% | 9 |
| %,100005,% | 2 |
+------------+---+
第一个查询需要 MySQL 8.0+ 或 MariaDB 10.2.2+。
第二个查询支持这些和旧版本。
-- This returns all the matching rows (to maintain your current result)
-- Plus adds `n` per row indicating the count of rows per matching pattern (chain)
-- I've included a better pattern be sure the right chains are identified.
WITH patterns (pattern) AS (
SELECT '%,100002,%' UNION ALL
SELECT '%,100005,%'
)
SELECT DP.team.parent_id AS Upline
, DP.users.id AS UserID
, DP.users.nickname AS Username
, DP.users.email AS Email
, DP.users.country AS Country
, DP.team.gene_chain
, DP.team.gene_num
, p.pattern
, COUNT(*) OVER (PARTITION BY p.pattern) AS n
FROM DP.team JOIN DP.users ON DP.team.user_id = DP.users.id
JOIN patterns AS p
ON CONCAT('%,', DP.team.gene_chain, ',%') LIKE p.pattern
ORDER BY p.pattern
;
结果:
+--------+--------+----------+-------+---------+---------------------------------------------+----------+------------+---+
| Upline | UserID | Username | Email | Country | gene_chain | gene_num | pattern | n |
+--------+--------+----------+-------+---------+---------------------------------------------+----------+------------+---+
| 100005 | 100009 | NULL | NULL | NULL | 0,100001,100002,100003,100005 | NULL | %,100002,% | 9 |
| 100004 | 100006 | NULL | NULL | NULL | 0,100001,100002,100004 | NULL | %,100002,% | 9 |
| 100002 | 100003 | NULL | NULL | NULL | 0,100001,100002 | NULL | %,100002,% | 9 |
| 100005 | 100010 | NULL | NULL | NULL | 0,100001,100002,100003,100005 | NULL | %,100002,% | 9 |
| 100007 | 100008 | NULL | NULL | NULL | 0,100001,100002,100004,100006,100007 | NULL | %,100002,% | 9 |
| 100003 | 100005 | NULL | NULL | NULL | 0,100001,100002,100003 | NULL | %,100002,% | 9 |
| 100008 | 100011 | NULL | NULL | NULL | 0,100001,100002,100004,100006,100007,100008 | NULL | %,100002,% | 9 |
| 100006 | 100007 | NULL | NULL | NULL | 0,100001,100002,100004,100006 | NULL | %,100002,% | 9 |
| 100002 | 100004 | NULL | NULL | NULL | 0,100001,100002 | NULL | %,100002,% | 9 |
| 100005 | 100010 | NULL | NULL | NULL | 0,100001,100002,100003,100005 | NULL | %,100005,% | 2 |
| 100005 | 100009 | NULL | NULL | NULL | 0,100001,100002,100003,100005 | NULL | %,100005,% | 2 |
+--------+--------+----------+-------+---------+---------------------------------------------+----------+------------+---+
并且还支持 MySQL 8.0 之前的版本等:
SELECT DP.team.parent_id AS Upline
, DP.users.id AS UserID
, DP.users.nickname AS Username
, DP.users.email AS Email
, DP.users.country AS Country
, DP.team.gene_chain
, DP.team.gene_num
, p.pattern
-- , COUNT(*) OVER (PARTITION BY p.pattern) AS n -- Not supported in 5.7 or before. We would do something else to count.
FROM DP.team JOIN DP.users ON DP.team.user_id = DP.users.id
JOIN (
SELECT '%,100002,%' AS pattern UNION ALL
SELECT '%,100005,%'
) AS p
ON CONCAT('%,', DP.team.gene_chain, ',%') LIKE p.pattern
ORDER BY p.pattern
;
结果:
+--------+--------+----------+-------+---------+---------------------------------------------+----------+------------+
| Upline | UserID | Username | Email | Country | gene_chain | gene_num | pattern |
+--------+--------+----------+-------+---------+---------------------------------------------+----------+------------+
| 100005 | 100009 | NULL | NULL | NULL | 0,100001,100002,100003,100005 | NULL | %,100002,% |
| 100004 | 100006 | NULL | NULL | NULL | 0,100001,100002,100004 | NULL | %,100002,% |
| 100002 | 100003 | NULL | NULL | NULL | 0,100001,100002 | NULL | %,100002,% |
| 100005 | 100010 | NULL | NULL | NULL | 0,100001,100002,100003,100005 | NULL | %,100002,% |
| 100007 | 100008 | NULL | NULL | NULL | 0,100001,100002,100004,100006,100007 | NULL | %,100002,% |
| 100003 | 100005 | NULL | NULL | NULL | 0,100001,100002,100003 | NULL | %,100002,% |
| 100008 | 100011 | NULL | NULL | NULL | 0,100001,100002,100004,100006,100007,100008 | NULL | %,100002,% |
| 100006 | 100007 | NULL | NULL | NULL | 0,100001,100002,100004,100006 | NULL | %,100002,% |
| 100002 | 100004 | NULL | NULL | NULL | 0,100001,100002 | NULL | %,100002,% |
| 100005 | 100009 | NULL | NULL | NULL | 0,100001,100002,100003,100005 | NULL | %,100005,% |
| 100005 | 100010 | NULL | NULL | NULL | 0,100001,100002,100003,100005 | NULL | %,100005,% |
+--------+--------+----------+-------+---------+---------------------------------------------+----------+------------+
测试用例的设置:
CREATE TABLE team (
id int primary key auto_increment
, user_id int
, parent_id int
, gene_chain varchar(100)
, gene_num int
);
CREATE TABLE users (
id int primary key
, nickname int
, email int
, country int
);
INSERT INTO users (id) VALUES
('100001')
, ('100002')
, ('100003')
, ('100004')
, ('100005')
, ('100006')
, ('100007')
, ('100008')
, ('100009')
, ('100010')
, ('100011')
, ('100012')
, ('100013')
, ('100014')
, ('100015')
;
INSERT INTO team (user_id, parent_id, gene_chain) VALUES
(100002, 100001, '0,100001')
, (100003, 100002, '0,100001,100002')
, (100004, 100002, '0,100001,100002')
, (100005, 100003, '0,100001,100002,100003')
, (100006, 100004, '0,100001,100002,100004')
, (100007, 100006, '0,100001,100002,100004,100006')
, (100008, 100007, '0,100001,100002,100004,100006,100007')
, (100009, 100005, '0,100001,100002,100003,100005')
, (100010, 100005, '0,100001,100002,100003,100005')
, (100011, 100008, '0,100001,100002,100004,100006,100007,100008')
;