连接多行分层数据

时间:2017-12-22 15:44:04

标签: mysql sql concat

票:

id_ticket |id_ticket_category |
----------|-------------------|
1         |8                  |
2         |8                  |
3         |13                 |

类别:

id_category |id_parent |label                             |id_category_type |
------------|----------|----------------------------------|-----------------|
1           |-1        |Demande d'information             |1                |
2           |-1        |Réclamation                       |1                |
3           |1         |Autre                             |2                |
4           |1         |Mairie                            |2                |
5           |1         |Stationnement                     |2                |
6           |2         |Autre                             |2                |
8           |3         |Autre                             |3                |
9           |4         |Réservation de salle              |3                |
10          |4         |Autre                             |3                |
11          |5         |Horaires de stationnement         |3                |
12          |5         |Autre                             |3                |
13          |6         |Autre                             |3                |
16          |7         |Autre                             |3                |

请注意id_ticket_category表中的Ticket列引用id_category表中的Category

我想返回带有id_parentof元素的concat的计数和id_ticket_category (id_category)行。

实施例

id_ticket_category = 8我查看Category

id_category |id_parent |label                             |id_category_type |
------------|----------|----------------------------------|-----------------|
8           |3         |Autre                             |3                |

我看id_parent

-1不相等
id_category |id_parent |label                             |id_category_type |
------------|----------|----------------------------------|-----------------|
3           |1         |Autre                             |2                |

我看是id_parent不等于-1

id_category |id_parent |label                             |id_category_type |
------------|----------|----------------------------------|-----------------|
1           |-1        |Demande d'information             |1                |

id_parent相等-1我打印结果

Category                 |count|
-------------------------|-----|
Autre-Demande Information| 2   | 

其实我有这个要求:

SELECT CONCAT(c.label, '-', parents.label), c.id_parent  
FROM Category c INNER JOIN
(SELECT id_category AS id, label FROM category c WHERE id_parent = -1) AS parents
ON parents.id = c.id_parent 
WHERE  c.id_category_type < 3 
ORDER BY c.id_category_type;

所以有人知道如何改善这个吗?

2 个答案:

答案 0 :(得分:2)

您可以创建以下程序来执行任务,

以下是程序:

DROP PROCEDURE IF EXISTS getConcatRows;

DELIMITER //

CREATE PROCEDURE getConcatRows(IN id_tc int)
 BEGIN

 DECLARE id_parent_tc int;
 SET id_parent_tc = id_tc;

 DROP temporary table IF EXISTS temp_category;

 # Create temporarty table to store hirarchy
 create TEMPORARY table temp_category 
 AS 
 select 0 as id_category,category.label,-1 as id_tc from category limit 1;


 WHILE id_parent_tc <> -1 
 DO
   insert into temp_category select id_category,label,id_tc from category WHERE id_category=id_parent_tc;

   SELECT id_parent into id_parent_tc FROM category WHERE id_category=id_parent_tc;
 END WHILE;

 # Subtract 1 since it will contain the total herarchy
 select GROUP_CONCAT(distinct label),count(1)-1 from temp_category t where t.id_tc = id_tc group by id_tc;
 END //

 DELIMITER ;

 CALL getConcatRows(8);
 # Will return the required output

答案 1 :(得分:2)

似乎您需要按类别对故障单进行分组并显示计数和路径。如果类别树最大深度为3级,则此方法有效:

SELECT
    id_ticket_category,
    CONCAT_WS(' > ', c3.label, c2.label, c1.label) AS `category`,
    COUNT(*) AS `count`
FROM ticket
LEFT JOIN category c1 ON ticket.id_ticket_category = c1.id_category
LEFT JOIN category c2 ON c1.id_parent = c2.id_category
LEFT JOIN category c3 ON c2.id_parent = c3.id_category
GROUP BY id_ticket_category, category

输出:

+--------------------+---------------------------------------+-------+
| id_ticket_category | category                              | count |
+--------------------+---------------------------------------+-------+
|                  8 | Demande d'information > Autre > Autre |     2 |
|                 13 | Réclamation > Autre > Autre           |     1 |
+--------------------+---------------------------------------+-------+

转换为嵌套集模型

nested set model在检索分层数据方面效率更高。但是,保持它可能很困难。如果您有兴趣,那么首先需要将数据转换为:

+-------------+-----------+---------------------------+------------------+------+------+
| id_category | id_parent | label                     | id_category_type | l    | r    |
+-------------+-----------+---------------------------+------------------+------+------+
|           1 |        -1 | Demande d'information     |                1 |    2 |   19 |
|           2 |        -1 | Réclamation               |                1 |   20 |   25 |
|           3 |         1 | Autre                     |                2 |    3 |    6 |
|           4 |         1 | Mairie                    |                2 |    7 |   12 |
|           5 |         1 | Stationnement             |                2 |   13 |   18 |
|           6 |         2 | Autre                     |                2 |   21 |   24 |
|           8 |         3 | Autre                     |                3 |    4 |    5 |
|           9 |         4 | Réservation de salle      |                3 |    8 |    9 |
|          10 |         4 | Autre                     |                3 |   10 |   11 |
|          11 |         5 | Horaires de stationnement |                3 |   14 |   15 |
|          12 |         5 | Autre                     |                3 |   16 |   17 |
|          13 |         6 | Autre                     |                3 |   22 |   23 |
|          16 |         7 | Autre                     |             NULL | NULL | NULL |
+-------------+-----------+---------------------------+------------------+------+------+

然后您可以使用此查询(对类别树的深度没有限制):

SELECT
    id_ticket_category,
    GROUP_CONCAT(DISTINCT CONCAT(parent.label, ' (', parent.id_category, ')') ORDER BY parent.l SEPARATOR ' > ') AS category,
    COUNT(DISTINCT id_ticket) AS `count`
FROM ticket
LEFT JOIN category ON ticket.id_ticket_category = category.id_category
LEFT JOIN category parent ON category.l BETWEEN parent.l AND parent.r
GROUP BY id_ticket_category

输出:

+--------------------+---------------------------------------------------+-------+
| id_ticket_category | category                                          | count |
+--------------------+---------------------------------------------------+-------+
|                  8 | Demande d'information (1) > Autre (3) > Autre (8) |     2 |
|                 13 | Réclamation (2) > Autre (6) > Autre (13)          |     1 |
+--------------------+---------------------------------------------------+-------+