具有嵌套集合模型的 GROUP_CONCAT

发布于 2024-11-13 13:48:26 字数 1839 浏览 4 评论 0原文

我有一个使用嵌套集模型类来组织数据的应用程序,但是我正在尝试编写一个查询来对我的结果进行 group_concat。我知道我需要在某处放置一些子选择语句,但我无法弄清楚!

这是我目前的结构:

table: person

 -----------+------------+-----------
|Person_ID  | Name       | Age       |
 -----------+------------+-----------
| 1         | Mark Vance | 19        |
| 2         | Michael Tsu| 22        |
| 3         | Mark Jones | 29        |
| 4         | Sara Young | 25        |
 -----------+------------+-----------

table: person_to_group

 ----+------------+-----------
|ID  | Person_ID  | Group_ID  |
 ----+------------+-----------
| 1  | 3          | 1         |
| 2  | 3          | 2         |
| 3  | 1          | 2         |
| 4  | 4          | 3         |
 ----+------------+-----------

table: groups

 ----------+--------------+--------------+-------------
|Group_ID  | Group_Name   | Group_Left   | Group_Right |
 ----------+--------------+--------------+-------------
| 1        | Root         | 1            | 6           |
| 2        | Node         | 2            | 5           |
| 3        | Sub Node     | 3            | 4           |
 ----------+--------------+--------------+-------------

我需要用我的结果呈现类似这样的内容:

//Grab the group_IDs for this person and put those in the class tag...

<li class="2 3">Sara Young is in the Sub Node Group</li>

请注意,虽然 Sara 是在子节点组中,她仍然被赋予节点的 id,因为她是节点的子节点。

以下是我正在使用的作为起点的查询。

SELECT *, GROUP_CONCAT( CAST( gg.Group_ID AS CHAR ) SEPARATOR ' ' ) Group_IDs
        FROM groups gg
        LEFT JOIN person_to_group AS t1 ON gg.Group_ID = t1.Group_ID
        LEFT JOIN person AS t2 ON t2.Person_ID = t1.Person_ID
        GROUP BY t2.per_ID 
        ORDER BY t2.Name ASC

任何帮助将不胜感激!

I have an application that uses a nested set model class to organise my data, however I'm trying to write a query that will group_concat my results. I know I need to put some sub select statements somewhere but I can't figure it out!

Here's my structure at the moment:

table: person

 -----------+------------+-----------
|Person_ID  | Name       | Age       |
 -----------+------------+-----------
| 1         | Mark Vance | 19        |
| 2         | Michael Tsu| 22        |
| 3         | Mark Jones | 29        |
| 4         | Sara Young | 25        |
 -----------+------------+-----------

table: person_to_group

 ----+------------+-----------
|ID  | Person_ID  | Group_ID  |
 ----+------------+-----------
| 1  | 3          | 1         |
| 2  | 3          | 2         |
| 3  | 1          | 2         |
| 4  | 4          | 3         |
 ----+------------+-----------

table: groups

 ----------+--------------+--------------+-------------
|Group_ID  | Group_Name   | Group_Left   | Group_Right |
 ----------+--------------+--------------+-------------
| 1        | Root         | 1            | 6           |
| 2        | Node         | 2            | 5           |
| 3        | Sub Node     | 3            | 4           |
 ----------+--------------+--------------+-------------

I need to render something like this with my results:

//Grab the group_IDs for this person and put them in the class tag...

<li class="2 3">Sara Young is in the Sub Node Group</li>

Notice that although Sara is in the Sub Node group, she is still being given the id for Node aswell because she is a child of Node.

The following is the query that I am working with as a starting point.

SELECT *, GROUP_CONCAT( CAST( gg.Group_ID AS CHAR ) SEPARATOR ' ' ) Group_IDs
        FROM groups gg
        LEFT JOIN person_to_group AS t1 ON gg.Group_ID = t1.Group_ID
        LEFT JOIN person AS t2 ON t2.Person_ID = t1.Person_ID
        GROUP BY t2.per_ID 
        ORDER BY t2.Name ASC

Any help would be much appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦在夏天 2024-11-20 13:48:26

以下是我编写查询的方式:

SELECT p.Name, 
  GROUP_CONCAT( g.Group_Name ) AS Group_List,
  GROUP_CONCAT( CAST( gg.Group_ID AS CHAR ) SEPARATOR ' ' ) AS Group_ID_List
FROM person AS p
INNER JOIN person_to_group AS pg ON p.Person_ID = pg.Person_ID
INNER JOIN groups AS g ON pg.Group_ID = g.Group_ID
INNER JOIN groups AS gg ON g.Group_Left BETWEEN gg.Group_Left AND gg.Group_Right
GROUP BY p.Name
ORDER BY p.Name ASC

请注意,如果按人名分组,则还需要 GROUP_CONCAT 组名称列表。根据您的架构,由于多对多关系,一个人可以属于多个组。

我还建议一般不要使用 SELECT *。只需指定您需要的列即可。

Here's how I'd write the query:

SELECT p.Name, 
  GROUP_CONCAT( g.Group_Name ) AS Group_List,
  GROUP_CONCAT( CAST( gg.Group_ID AS CHAR ) SEPARATOR ' ' ) AS Group_ID_List
FROM person AS p
INNER JOIN person_to_group AS pg ON p.Person_ID = pg.Person_ID
INNER JOIN groups AS g ON pg.Group_ID = g.Group_ID
INNER JOIN groups AS gg ON g.Group_Left BETWEEN gg.Group_Left AND gg.Group_Right
GROUP BY p.Name
ORDER BY p.Name ASC

Note that if you group by person name, you also need to GROUP_CONCAT the list of group names. According to your schema, a person could belong to multiple groups, because of the many-to-many relationship.

I also recommend against using SELECT * in general. Just specify the columns you need.

眼前雾蒙蒙 2024-11-20 13:48:26

这有点有趣,因为我同时使用 MsSQL 和 MySql 进行编程。在 SQL 中我使用了名为 STUFF 的函数。在 MySQL 中,您可以使用名为 INSERT 的函数。我在 MsSQL 中尝试了以下查询。手边没有 MySQL 来尝试我的查询。如果我有时间我会发布该查询的 MySQL 版本。

DECLARE @person TABLE (Person_ID INT, Name VARCHAR(50), Age INT)
INSERT INTO @person VALUES
(1,'Mark Vance',19),
(2,'Michael Tsu',22),
(3,'Mark Jones',29),
(4,'Sara Young',25)


DECLARE @groups TABLE (Group_ID INT, Group_Name VARCHAR(50), Group_Left INT, Group_Right INT)
INSERT INTO @groups VALUES
(1,'Root',1,6),
(2,'Node',2,5),
(3,'Sub Node',3,4)

DECLARE @person_to_group TABLE (ID INT, Person_ID INT, Group_ID INT)
INSERT INTO @person_to_group VALUES
(1,3,1),
(2,3,2),
(3,1,1),
(4,4,1),
(4,1,1)

SELECT *,STUFF((SELECT ',' + CAST(g.Group_ID AS VARCHAR) FROM @groups g 
    JOIN @person_to_group pg ON g.Group_ID = pg.Group_ID AND pg.Person_ID = a.Person_ID FOR XML PATH('')) , 1, 1, '' ) FROM @person a

函数:INSERT(str,pos,len,newstr)
文档http:// dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_insert

This was little bit interesting as I do programming in both MsSQL and MySql. In SQL I have used function called STUFF. In MySQL you can use a function called INSERT. I tried out the below query in MsSQL. Don't have a MySQL handy to try out my query. If I have time I will post the MySQL version of the query.

DECLARE @person TABLE (Person_ID INT, Name VARCHAR(50), Age INT)
INSERT INTO @person VALUES
(1,'Mark Vance',19),
(2,'Michael Tsu',22),
(3,'Mark Jones',29),
(4,'Sara Young',25)


DECLARE @groups TABLE (Group_ID INT, Group_Name VARCHAR(50), Group_Left INT, Group_Right INT)
INSERT INTO @groups VALUES
(1,'Root',1,6),
(2,'Node',2,5),
(3,'Sub Node',3,4)

DECLARE @person_to_group TABLE (ID INT, Person_ID INT, Group_ID INT)
INSERT INTO @person_to_group VALUES
(1,3,1),
(2,3,2),
(3,1,1),
(4,4,1),
(4,1,1)

SELECT *,STUFF((SELECT ',' + CAST(g.Group_ID AS VARCHAR) FROM @groups g 
    JOIN @person_to_group pg ON g.Group_ID = pg.Group_ID AND pg.Person_ID = a.Person_ID FOR XML PATH('')) , 1, 1, '' ) FROM @person a

Function: INSERT(str,pos,len,newstr)
Documentation: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_insert

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文