我有一张表格如下
CREATE TABLE member
(
id VARCHAR(11) PRIMARY KEY NOT NULL,
referral_id VARCHAR(10) NOT NULL,
first_name VARCHAR(100) NOT NULL,
surname VARCHAR(100) NOT NULL,
address VARCHAR(100) NOT NULL,
country VARCHAR(20) NOT NULL,
phone VARCHAR(20) NOT NULL,
account_no VARCHAR(20) NOT NULL,
account_name VARCHAR(100) NOT NULL,
bank_name VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
voucher_code VARCHAR(20) NOT NULL,
vcode_activated VARCHAR(2) NOT NULL,
current_level VARCHAR(2) NOT NULL,
extra_downlines VARCHAR(2) NOT NULL,
password VARCHAR(100) NOT NULL,
status VARCHAR(2) NOT NULL,
primary_downlines VARCHAR(2) NOT NULL,
date_registered VARCHAR(12) NOT NULL,
completed_level1 VARCHAR(2) NOT NULL,
referral_bonus VARCHAR(10) DEFAULT '0',
signup_earning VARCHAR(10) DEFAULT '0'
);
INSERT INTO member (id, referral_id, first_name, surname, address, country, phone, account_no, account_name, bank_name, email, voucher_code, vcode_activated, completed_level1, current_level, primary_downlines, extra_downlines, password, status, date_registered, referral_bonus, signup_earning) VALUES ('100000', '0', 'Mose', 'Alfi', 'MKd', 'NA', '098', '987', 'Alfi', 'gtb', 'al@yahc.com', '1504895239', '0', '1', '0', '', '1', 'a', '', '', '2000', '2000');
INSERT INTO member (id, referral_id, first_name, surname, address, country, phone, account_no, account_name, bank_name, email, voucher_code, vcode_activated, completed_level1, current_level, primary_downlines, extra_downlines, password, status, date_registered, referral_bonus, signup_earning) VALUES ('100001', '100000', 'Ush', 'Alim', 'Mkd', 'AD', '0949490', '0987', 'Ush', 'FBN', 'us@alim.com', '', '0', '', '0', '', '0', 'ali', '0', '', '0', '0');
INSERT INTO member (id, referral_id, first_name, surname, address, country, phone, account_no, account_name, bank_name, email, voucher_code, vcode_activated, completed_level1, current_level, primary_downlines, extra_downlines, password, status, date_registered, referral_bonus, signup_earning) VALUES ('100002', '100000', 'Tork', 'Alik', 'Mkd', 'AU', '0987', '098', 'Tor', 'Diamond', 'torku@alik.com', '', '0', '', '0', '', '0', 'ali', '0', '', '0', '0');
INSERT INTO member (id, referral_id, first_name, surname, address, country, phone, account_no, account_name, bank_name, email, voucher_code, vcode_activated, completed_level1, current_level, primary_downlines, extra_downlines, password, status, date_registered, referral_bonus, signup_earning) VALUES ('100003', '0', 'Te', 'Aliu', 'Gboko', 'AD', '09809', '798', 'Aliu Ter', 'Stanbic', 'ali@er.com', '', '0', '0', '1', '0', '0', 'ali', '0', '2017-09-11', '0', '0');
INSERT INTO member (id, referral_id, first_name, surname, address, country, phone, account_no, account_name, bank_name, email, voucher_code, vcode_activated, completed_level1, current_level, primary_downlines, extra_downlines, password, status, date_registered, referral_bonus, signup_earning) VALUES ('100004', '100000', 'Alex', 'Alis', 'mkd', 'NI', '9890', '99', 'Alex', 'Eco', 'alis@yshso.com', '', '0', '0', '1', '0', '0', 'alex', '0', '2017-09-11', '0', '0');
INSERT INTO
member (id, referral_id, first_name, surname, address, country, phone, account_no, account_name, bank_name, email, voucher_code, vcode_activated, completed_level1, current_level, primary_downlines, extra_downlines, password, status, date_registered, referral_bonus, signup_earning) VALUES ('100005', '100000', 'Alx', 'Alki', 'mkd', 'NI', '9890', '99', 'Alx', 'Eco', 'alki@yshso.com', '', '0', '0', '1', '0', '0', 'alex', '0', '2017-09-11', '0', '0');
在上面的成员表中,id是成员id,referral_id是引用该成员的成员的id。 会员将推荐3名将成为会员的人,每人将推荐3人。 如何让一位未提及最多3人的会员? 我如何获得成员和他所推荐的人的分层显示?
答案 0 :(得分:0)
对于你应该做的问题的第一部分。粗略解释一下这个问题:我们需要一个查询的UNION来计算所有推荐超过零但少于3人的人和查询,这些人会列出所有没有推荐任何人的人。
(SELECT referring.id,
GROUP_CONCAT(
CONCAT(referred.first_name, ' ', referred.surname)
) as Referred,
CONCAT(referring.first_name, ' ', referring.surname) as Referral,
COUNT(referred.id) as cnt
FROM member AS referred
LEFT JOIN member AS referring ON referring.id = referred.referral_id
GROUP BY referred.referral_id
HAVING cnt < 3)
UNION
(SELECT referring.id, 'nobody' as Referred,
CONCAT(referring.first_name, ' ', referring.surname) as Referral,
0 as cnt
FROM member AS referring
WHERE referring.id NOT IN (SELECT referral_id FROM member))
http://sqlfiddle.com/#!9/dc0b8/29
[UPDATE]
至于问题的第二部分,为了在PHP中进行树遍历,您可以修改查询,以便它也列出引用的ID:
(SELECT referring.id, GROUP_CONCAT(CONCAT(referred.first_name, ' ', referred.surname)) as Referred,
GROUP_CONCAT(referred.id) as Referred_ids,
CONCAT(referring.first_name, ' ', referring.surname) as Referral,
COUNT(referred.id) as cnt
FROM member AS referred
LEFT JOIN member AS referring ON referring.id = referred.referral_id
GROUP BY referred.referral_id
HAVING cnt < 3)
UNION
(SELECT referring.id, 'nobody' as Referred,
'null' as Referred_ids,
CONCAT(referring.first_name, ' ', referring.surname) as Referral,
0 as cnt
FROM member AS referring
WHERE referring.id NOT IN (SELECT referral_id FROM member) )
http://sqlfiddle.com/#!9/dc0b8/32
子项的ID可能是构建层次结构树视图的起点。 但是有一个很大但是
在MySQL中表示分层数据实际上是非常棘手的主题。表示数据的方式称为邻接列表,是最简单的形式,但是导致树检索和管理(添加删除数据等)的许多问题。 According to many it is an antipattern
在您的特定情况下,检索问题可能更加严重,因为您的推荐树将会非常深入。查询表示没有固定数量嵌套级别的树的邻接列表很难。
看一下这篇伟大的文章,figure out problems that might lay in front of you, and possible solutions(db中的替代表示)
答案 1 :(得分:0)
一个查询来统治它们!在这里你去amigo!
SELECT * FROM blah WHERE id =
(SELECT rid
FROM blah
GROUP BY rid
HAVING COUNT(DISTINCT id) < 3);
答案 2 :(得分:0)
此表达式返回主要父级(id 100000)的子级(包括大子级),其子级少于3个。
SELECT `id`, `referral_id` AS `parent_id`, `children`
FROM (SELECT `id`, `referral_id`, (SELECT COUNT(`id`) FROM `member` AS `r` WHERE r.`referral_id` = m.`id`) AS `children` FROM `member` AS `m` ORDER BY `referral_id`, `id`) AS `members`,
(SELECT @pv := '100000') AS `init`
WHERE FIND_IN_SET(`referral_id`, @pv) > 0 AND @pv := CONCAT(@pv, ',', `id`)
HAVING `children` < 3
http://sqlfiddle.com/#!9/885878/4
如果一名成员有3个或更多孩子,那么其大孩子也将被排除在结果之外。
SELECT `id`, `referral_id` AS `parent_id`, `children`
FROM (SELECT `id`, `referral_id`, (SELECT COUNT(`id`) FROM `member` AS `r` WHERE r.`referral_id` = m.`id`) AS `children` FROM `member` AS `m` HAVING `children` < 3 ORDER BY `referral_id`, `id`) AS `members`,
(SELECT @pv := '100000') AS `init`
WHERE FIND_IN_SET(`referral_id`, @pv) > 0 AND @pv := CONCAT(@pv, ',', `id`)
http://sqlfiddle.com/#!9/885878/5
在这个答案中,您可以找到有关递归查询的其他信息。 https://stackoverflow.com/a/33737203/4020014