GROUP_CONCAT 内的 CONCAT - 如何删除重复结果
CONCAT within GROUP_CONCAT - How to remove duplicate result
CONCAT
在 GROUP_CONCAT
内,下面的 mysql 代码有什么问题?请参阅 SQL Fiddle,那里有完整的代码。
让我解释一下,我有5个table
cls - Classes
列表
sec - 章节列表
费用 - 费用列表
cls_sec - 分配给每个 class
的部分列表
cls_fee - 分配给每个部分的费用列表
Table cls
- Class
列表
id | ttl
===========
1 | One
2 | Two
3 | Three
Table sec
- 部分列表
id | ttl
===========
1 | A
2 | B
Table cls_sec
- 分配给 Class
的每个部分的列表
id | c_id| s_id
=====================
1 | 1 | 1
2 | 1 | 2
3 | 2 | 1
Table fee
- 费用类别列表
id | ttl
===========
1 | Annual
2 | Monthly
3 | Library
Table cls_fee
- 分配给 Class
的每笔费用和金额的列表
id | c_id| s_id| f_id| fee
=====================================
1 | 1 | 1 | 1 | 2000
2 | 1 | 1 | 2 | 500
3 | 1 | 2 | 1 | 3000
4 | 1 | 2 | 2 | 400
5 | 2 | 1 | 1 | 4500
6 | 2 | 1 | 2 | 450
7 | 3 | 0 | 1 | 5000
8 | 3 | 0 | 2 | 600
9 | 3 | 0 | 3 | 300
这里我试图将所有关系包含在一个 GROUP_CONCAT
结果中
我现在的输出(Class name和section name是根据fee重复获取的)
//Class Name - Section Name (if exist) - fee, Class Name - Section Name (if exist) - fee ..
3.Three.Library->300, 3.Three.Monthly->600, 3.Three.Annual->5000,
2.Two-A.Monthly->450, 2.Two-A.Annual->4500, 1.One-A.Monthly->500,
1.One-A.Annual->2000, 1.One-B.Monthly->400, 1.One-B.Annual->3000
使用以下代码
GROUP_CONCAT(DISTINCT CONCAT('\r\n',cls.id,'.',cls.ttl,
COALESCE(CONCAT('-',sec.ttl),''),COALESCE(CONCAT('.',fee.ttl,'->',cls_fee.fee)))
ORDER BY sec.id) AS cls
但我想要的(删除重复class和部分)
//Class Name - Section Name (if exists) - fee, fee
3.Three.Library->300,Monthly->600,Annual->5000,
2.Two-A.Monthly->450,Annual->4500,
1.One-A.Monthly->500,Annual->2000,
1.One-B.Monthly->400,Annual->3000
所以我在嵌套的 CONCAT
中添加 CONCAT
GROUP_CONCAT(DISTINCT CONCAT('\r\n',cls.id,'.',cls.ttl,
COALESCE(CONCAT('-',sec.ttl,COALESCE(CONCAT('.',fee.ttl,'->',cls_fee.fee))), ''))
ORDER BY sec.id) AS cls
并获得了输出,但未按预期获取,还缺少一些费用
3.Three,
2.Two-A.Monthly->450, 2.Two-A.Annual->4500,
1.One-A.Monthly->500, 1.One-A.Annual->2000,
1.One-B.Monthly->400, 1.One-B.Annual->3000
MySQL 代码
SELECT
GROUP_CONCAT(DISTINCT CONCAT('\r\n',cls.id,'.',cls.ttl,
COALESCE(CONCAT('-',sec.ttl),''),COALESCE(CONCAT('.',fee.ttl,'->',cls_fee.fee)))
ORDER BY sec.id) AS cls
FROM
cls
LEFT JOIN
cls_sec ON cls_sec.cls = cls.id
LEFT JOIN
sec ON sec.id = cls_sec.sec
LEFT JOIN
cls_fee ON cls_fee.c_id = cls.id
LEFT JOIN
fee ON fee.id = cls_fee.f_id
WHERE
CASE WHEN cls_fee.s_id != 0 THEN cls_fee.s_id = sec.id ELSE cls.id END
您可以尝试使用子查询从详细信息 cls.id, cls.ttl
写入 GROUP_CONCAT
然后在主查询中再次执行 GROUP_CONCAT
。
查询 1:
SELECT GROUP_CONCAT(CONCAT(Id,'.',ttl,'.',flag,cls) ORDER BY Id desc,flag) result
FROM (
SELECT
cls.id,
cls.ttl,
COALESCE(CONCAT('-',sec.ttl),'') flag,
GROUP_CONCAT(DISTINCT CONCAT(
COALESCE(CONCAT('.',fee.ttl,'->',cls_fee.fee)))
ORDER BY sec.id) AS cls
FROM
cls
LEFT JOIN
cls_sec ON cls_sec.cls = cls.id
LEFT JOIN
sec ON sec.id = cls_sec.sec
LEFT JOIN
cls_fee ON cls_fee.c_id = cls.id
LEFT JOIN
fee ON fee.id = cls_fee.f_id
WHERE
CASE WHEN cls_fee.s_id != 0 THEN cls_fee.s_id = sec.id ELSE cls.id END
GROUP BY
cls.id,
cls.ttl,
COALESCE(CONCAT('-',sec.ttl),'')
)t1
| result |
|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 3.Three..Library->300,.Monthly->600,.Annual->5000,2.Two.-A.Monthly->450,.Annual->4500,1.One.-A.Monthly->500,.Annual->2000,1.One.-B.Monthly->400,.Annual->3000 |
CONCAT
在 GROUP_CONCAT
内,下面的 mysql 代码有什么问题?请参阅 SQL Fiddle,那里有完整的代码。
让我解释一下,我有5个table
cls - Classes
列表sec - 章节列表
费用 - 费用列表
cls_sec - 分配给每个 class
的部分列表cls_fee - 分配给每个部分的费用列表
Table cls
- Class
id | ttl
===========
1 | One
2 | Two
3 | Three
Table sec
- 部分列表
id | ttl
===========
1 | A
2 | B
Table cls_sec
- 分配给 Class
id | c_id| s_id
=====================
1 | 1 | 1
2 | 1 | 2
3 | 2 | 1
Table fee
- 费用类别列表
id | ttl
===========
1 | Annual
2 | Monthly
3 | Library
Table cls_fee
- 分配给 Class
id | c_id| s_id| f_id| fee
=====================================
1 | 1 | 1 | 1 | 2000
2 | 1 | 1 | 2 | 500
3 | 1 | 2 | 1 | 3000
4 | 1 | 2 | 2 | 400
5 | 2 | 1 | 1 | 4500
6 | 2 | 1 | 2 | 450
7 | 3 | 0 | 1 | 5000
8 | 3 | 0 | 2 | 600
9 | 3 | 0 | 3 | 300
这里我试图将所有关系包含在一个 GROUP_CONCAT
结果中
我现在的输出(Class name和section name是根据fee重复获取的)
//Class Name - Section Name (if exist) - fee, Class Name - Section Name (if exist) - fee ..
3.Three.Library->300, 3.Three.Monthly->600, 3.Three.Annual->5000,
2.Two-A.Monthly->450, 2.Two-A.Annual->4500, 1.One-A.Monthly->500,
1.One-A.Annual->2000, 1.One-B.Monthly->400, 1.One-B.Annual->3000
使用以下代码
GROUP_CONCAT(DISTINCT CONCAT('\r\n',cls.id,'.',cls.ttl,
COALESCE(CONCAT('-',sec.ttl),''),COALESCE(CONCAT('.',fee.ttl,'->',cls_fee.fee)))
ORDER BY sec.id) AS cls
但我想要的(删除重复class和部分)
//Class Name - Section Name (if exists) - fee, fee
3.Three.Library->300,Monthly->600,Annual->5000,
2.Two-A.Monthly->450,Annual->4500,
1.One-A.Monthly->500,Annual->2000,
1.One-B.Monthly->400,Annual->3000
所以我在嵌套的 CONCAT
CONCAT
GROUP_CONCAT(DISTINCT CONCAT('\r\n',cls.id,'.',cls.ttl,
COALESCE(CONCAT('-',sec.ttl,COALESCE(CONCAT('.',fee.ttl,'->',cls_fee.fee))), ''))
ORDER BY sec.id) AS cls
并获得了输出,但未按预期获取,还缺少一些费用
3.Three,
2.Two-A.Monthly->450, 2.Two-A.Annual->4500,
1.One-A.Monthly->500, 1.One-A.Annual->2000,
1.One-B.Monthly->400, 1.One-B.Annual->3000
MySQL 代码
SELECT
GROUP_CONCAT(DISTINCT CONCAT('\r\n',cls.id,'.',cls.ttl,
COALESCE(CONCAT('-',sec.ttl),''),COALESCE(CONCAT('.',fee.ttl,'->',cls_fee.fee)))
ORDER BY sec.id) AS cls
FROM
cls
LEFT JOIN
cls_sec ON cls_sec.cls = cls.id
LEFT JOIN
sec ON sec.id = cls_sec.sec
LEFT JOIN
cls_fee ON cls_fee.c_id = cls.id
LEFT JOIN
fee ON fee.id = cls_fee.f_id
WHERE
CASE WHEN cls_fee.s_id != 0 THEN cls_fee.s_id = sec.id ELSE cls.id END
您可以尝试使用子查询从详细信息 cls.id, cls.ttl
写入 GROUP_CONCAT
然后在主查询中再次执行 GROUP_CONCAT
。
查询 1:
SELECT GROUP_CONCAT(CONCAT(Id,'.',ttl,'.',flag,cls) ORDER BY Id desc,flag) result
FROM (
SELECT
cls.id,
cls.ttl,
COALESCE(CONCAT('-',sec.ttl),'') flag,
GROUP_CONCAT(DISTINCT CONCAT(
COALESCE(CONCAT('.',fee.ttl,'->',cls_fee.fee)))
ORDER BY sec.id) AS cls
FROM
cls
LEFT JOIN
cls_sec ON cls_sec.cls = cls.id
LEFT JOIN
sec ON sec.id = cls_sec.sec
LEFT JOIN
cls_fee ON cls_fee.c_id = cls.id
LEFT JOIN
fee ON fee.id = cls_fee.f_id
WHERE
CASE WHEN cls_fee.s_id != 0 THEN cls_fee.s_id = sec.id ELSE cls.id END
GROUP BY
cls.id,
cls.ttl,
COALESCE(CONCAT('-',sec.ttl),'')
)t1
| result |
|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 3.Three..Library->300,.Monthly->600,.Annual->5000,2.Two.-A.Monthly->450,.Annual->4500,1.One.-A.Monthly->500,.Annual->2000,1.One.-B.Monthly->400,.Annual->3000 |