我如何得到父母的大孩子或曾孙子女

时间:2017-09-12 14:08:39

标签: php mysql

我有一张表格如下

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人的会员? 我如何获得成员和他所推荐的人的分层显示?

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);

http://sqlfiddle.com/#!9/7046f2/17

答案 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