WHERE子句中的id来自上一行时的SELECT数据

时间:2016-12-23 07:17:05

标签: mysql sql

我有2张桌子。第一个包含最后一个操作的id,第二个 - 操作ID和一些数据

mysql> select * from t1;
+----+--------------+
| id | id_last_oper |
+----+--------------+
|  1 |           45 |
+----+--------------+

mysql> select * from t2;
+-------+------------+---------+
| fo_id | fo_prev_id | fo_name |
+-------+------------+---------+
|     1 |       NULL | a       |
|     5 |          1 | a       |
|    22 |          5 | a       |
|    45 |         22 | a       |
+-------+------------+---------+

这是我的问题:

select fo_id from t2 
           where fo_id=44 and @id:=fo_prev_id 
    union select fo_id from t2 where fo_id=@id
    union ...;

我需要选择所有行,但行数是非永久性的,我无法选择简单UNION的所有行。我怎样才能实现目标?

2 个答案:

答案 0 :(得分:3)

几个月前我遇到了同样的问题。 有两种解决方案。

解决方案1(推荐) - 使用“左/右关系”
关系数据库不是为分层结构设计的。这个链接帮助我改变表的结构以使用分层结构。它使用起来快速简便: http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
我建议您使用此解决方案,因为它独立于您使用的数据库,我的经验始终是积极的

解决方案2 - 存储过程
在这种情况下,您可以递归调用存储过程本身。在这个声明中,很好地解释了。如果向下滚动更多,请参阅解决方案1中的相同链接 mysql stored procedure that calls itself recursively

答案 1 :(得分:0)

我不确定这是不是你要找的东西:

SELECT result.*
FROM (
    SELECT
        (select fo_id FROM t2 where fo_id = @xid ) as ids
        , @xid := (select `fo_prev_id` FROM t2 where fo_id = @xid ) as next_id
        , @row := @row +1 as row_order
    FROM t2 AS dummy
    CROSS JOIN (SELECT @xid := 45, @row := 0) as init
) AS orderd_ids
LEFT JOIN t2 AS result ON result.`fo_id` = orderd_ids.ids
ORDER BY orderd_ids.row_order;

<强>样品

mysql> SELECT * FROM t2;                                                                                                                                                                                 +-------+------------+---------+
| fo_id | fo_prev_id | fo_name |
+-------+------------+---------+
|     1 |       NULL | a       |
|     5 |          1 | a       |
|    22 |          5 | a       |
|    45 |         22 | a       |
+-------+------------+---------+
4 rows in set (0,00 sec)

mysql> SELECT result.*
    -> FROM (
    ->     SELECT
    ->          (select fo_id FROM t2 where fo_id = @xid ) as ids
    ->          , @xid := (select `fo_prev_id` FROM t2 where fo_id = @xid ) as next_id
    ->          , @row := @row +1 as row_order
    ->      FROM t2 AS dummy
    ->      CROSS JOIN (SELECT @xid := 45, @row := 0) as init
    -> ) AS orderd_ids
    -> LEFT JOIN t2 AS result ON result.`fo_id` = orderd_ids.ids
    -> ORDER BY orderd_ids.row_order;
+-------+------------+---------+
| fo_id | fo_prev_id | fo_name |
+-------+------------+---------+
|    45 |         22 | a       |
|    22 |          5 | a       |
|     5 |          1 | a       |
|     1 |       NULL | a       |
+-------+------------+---------+
4 rows in set (0,00 sec)

mysql>

样本2

mysql> SELECT * FROM t2;
+-------+------------+---------+
| fo_id | fo_prev_id | fo_name |
+-------+------------+---------+
|     1 |         66 | a       |
|     5 |          1 | a       |
|    22 |          5 | a       |
|    45 |         22 | a       |
|    66 |         72 | a       |
|    72 |       NULL | a       |
+-------+------------+---------+
6 rows in set (0,00 sec)

mysql> SELECT result.*
    -> FROM (
    ->     SELECT
    ->          (select fo_id FROM t2 where fo_id = @xid ) as ids
    ->          , @xid := (select `fo_prev_id` FROM t2 where fo_id = @xid ) as next_id
    ->          , @row := @row +1 as row_order
    ->      FROM t2 AS dummy
    ->      CROSS JOIN (SELECT @xid := 45, @row := 0) as init
    -> ) AS orderd_ids
    -> LEFT JOIN t2 AS result ON result.`fo_id` = orderd_ids.ids
    -> ORDER BY orderd_ids.row_order;
+-------+------------+---------+
| fo_id | fo_prev_id | fo_name |
+-------+------------+---------+
|    45 |         22 | a       |
|    22 |          5 | a       |
|     5 |          1 | a       |
|     1 |         66 | a       |
|    66 |         72 | a       |
|    72 |       NULL | a       |
+-------+------------+---------+
6 rows in set (0,00 sec)

mysql>