php - 如何使用自连接读取MySQL中的分层数据?

标签 php mysql self-join

我有一个名为“offers”的表;这是我的结构:

|  id   | rep_id |
------------------
| 25704 | 25060  |
| 25060 | 24419  |
| 24419 | 23785  |
| 23785 |  NULL  |

让我们从offer.id 23785(最后一行)开始,这是第一个offer,因此转发id(rep_id)为NULL,一天后23785将使用新id转发,这次是24419,我知道它是 23785,24419 将是 25060,依此类推。

现在,我的任务是调用上述任何 ID 并确定该优惠已重新发布的次数并列出所有内容。例如,如果我说我想知道 25060 已转发了多少次,它应该会产生上述所有 id,因为它们以一种奇怪的方式连接,但我不知道如何告诉 MySQL 它们已连接。我知道这不是最好的结构,但这就是我所拥有的。

我的查询:

SELECT go1.id, go1.rep_id
            FROM offers go1
            JOIN offers go2
            ON go2.rep_id = go1.rep_id
            WHERE go1.rep_id = 24419 OR go1.id = 24419

我的结果:

|  id   | rep_id |
------------------
| 25060 | 24419  |
| 24419 | 23785  |

想要的结果:

|  id   | rep_id |
------------------
| 25704 | 25060  |
| 25060 | 24419  |
| 24419 | 23785  |
| 23785 |  NULL  |

附注如果 MySQL 无法单独做到这一点,那么 PHP 将如何做到这一点?

最佳答案

以下是如何使用 MySQL 查询来完成此操作。无需为此使用 PHP:

SELECT 
    Id, 
    rep_id  
FROM(
    SELECT
        @r AS _id,
        (SELECT @r := Id FROM posts WHERE rep_id = _id) AS parent_id,
        @l := @l + 1 AS lvl
    FROM
        (SELECT @r :=23785, @l := 0) vars,posts m
    WHERE @r <> 0) T1
JOIN posts T2
    ON T1._id = T2.Id
GROUP BY Id
ORDER BY T1.lvl DESC;

输出

|    ID | REP_ID |
|-------|--------|
| 25704 |  25060 |
| 25060 |  24419 |
| 24419 |  23785 |
| 23785 |      0 |

SQL Fiddle Demo

看看这个

 (SELECT @r :=23785, @l := 0) vars,

您只需提供起始 ID,就像我提供的 23785

ID为25060

输出

|    ID | REP_ID |
|-------|--------|
| 25704 |  25060 |
| 25060 |  24419 |

SQL Fiddle Demo

有关其工作原理的更多详细信息 can be found here .

如果您想提供一些中间 ID,请使用此查询

SELECT 
    * 
FROM (
    (
    SELECT 
        num,    
        Id, 
        rep_id  
    FROM(
        SELECT
            @r AS _id,
            (SELECT @r := Id FROM posts WHERE rep_id = _id) AS parent_id,
            @l := @l + 1 AS lvl
        FROM
        (SELECT @r :=25060, @l := 0) vars,posts m
    WHERE @r <> 0) T1
    JOIN posts T2
        ON T1._id = T2.Id
    GROUP BY Id
    ORDER BY T1.lvl DESC
    ) UNION (
    SELECT 
        num,
        Id, 
        rep_id  
    FROM(
        SELECT
            @r AS _id,
            (SELECT @r := MAX(rep_id) FROM posts WHERE Id = _id) AS parent_id,
            @l := @l + 1 AS lvl
        FROM
        (SELECT @r :=25060, @l := 0) vars,posts m
        WHERE @r <> 0) T1
    JOIN posts T2
        ON T1._id = T2.Id
    GROUP BY Id
    ORDER BY T1.lvl DESC )
)l 
ORDER BY num

SQL Fiddle Demo

输出

| NUM |    ID | REP_ID |
|-----|-------|--------|
|   1 | 25704 |  25060 |
|   2 | 25060 |  24419 |
|   3 | 24419 |  23785 |
|   4 | 23785 |      0 |

关于php - 如何使用自连接读取MySQL中的分层数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20681436/

相关文章:

php - MySQLi 和 PDO 学什么比较好?

MySQL如何加入同一个表,包括丢失的行

sql - 希望删除 CTE 上丑陋的自连接

MySQL 从具有一列的表创建两列

php - 基于与 mySQL 表的正匹配将数组中的某些字符串组合在一起

php 返回 null 而 mysql 返回用户变量的值

php - 如何使用PHP PDO跨平台进行用户名/密码管理

mysql - 当我在 MySQL 中使用 'select' 时,如何将表中的所有日期放入新列中?

php - Xampp mysql 错误 : MySQL shutdown unexpectedly

javascript - 如何使用表单中的action属性管理自动提交