MySQL - 多行1个id并将多列数据转换为逗号分隔的行

问题描述 投票:0回答:2

我有一个数据库表: 请求人员ID列,用于分隔每个请求(reqid) 类别ID列,用于分隔请求中的每个项目的不同类别(catid) 项目ID列,用于分隔类别(itemid)中的每个项目类型 项目名称列,列出项目的名称(项目) 项目描述符列,给出项目的描述(desc) 和金额列,给出该类别中每个项目的总成本(金额)

所以我的表看起来像这样:

|---------|-------|----------|--------|-------|------------|
|  reqid  | catid | itemid   | item   | desc  | amount     | 
|---------|-------|----------|--------|-------|------------|
|  1      | 3     | 16       | food   | food  | 200        | 
|---------|-------|----------|--------|-------|------------|
|  1      | 3     | 17       | water  | wtr   | 50         | 
|---------|-------|----------|--------|-------|------------|
|  1      | 3     | 18       | film   | film  | 20         | 
|---------|-------|----------|--------|-------|------------|
|  1      | 5     | 30       | room   | room  | 500        | 
|---------|-------|----------|--------|-------|------------|
|  1      | 5     | 31       | chair  | chair | 150        | 
|---------|-------|----------|--------|-------|------------|
|  2      | 3     | 16       | food   | food  | 200        | 
|---------|-------|----------|--------|-------|------------|
|  2      | 3     | 17       | water  | wtr   | 50         | 
|---------|-------|----------|--------|-------|------------|
|  3      | 3     | 18       | film   | film  | 20         | 
|---------|-------|----------|--------|-------|------------|
|  3      | 5     | 30       | room   | room  | 500        | 
|---------|-------|----------|--------|-------|------------|
|  3      | 5     | 31       | chair  | chair | 150        | 
|---------|-------|----------|--------|-------|------------|

我希望我的查询结果看起来像

|--------|------------------|----------------------|--------------------|--------------------|
| reqid  | catid3itemid     | catid3item           | catid3desc         | catid3amount       | 
|--------|------------------|----------------------|--------------------|--------------------|
|  1     |16, 17, 18        | food, water, film    | food, wtr, film    | 200, 50, 20        | 
|--------|------------------|----------------------|--------------------|--------------------|
|  2     |16, 17            | food, water          |food, wtr           | 200, 50,           | 
|--------|------------------|----------------------|--------------------|--------------------|
|  3     |18                | film                 | film               | 20                 | 
|--------|------------------|----------------------|--------------------|--------------------|

继续:

|------------------|----------------------|--------------------|--------------------|
| catid4itemid     | catid4item           | catid4desc         | catid4amount       | 
|------------------|----------------------|--------------------|--------------------|
|                  |                      |                    |                    | 
|------------------|----------------------|--------------------|--------------------|
|                  |                      |                    |                    | 
|------------------|----------------------|--------------------|--------------------|
|                  |                      |                    |                    | 
|------------------|----------------------|--------------------|--------------------|

续决赛:

|------------------|----------------------|--------------------|--------------------|
| catid5itemid     | catid5item           | catid5desc         | catid5amount       | 
|------------------|----------------------|--------------------|--------------------|
|30,31             |room, chair           |room, chair         | 500, 150           | 
|------------------|----------------------|--------------------|--------------------|
|                  |                      |                    |                    | 
|------------------|----------------------|--------------------|--------------------|
|30,31             |room, chair           |room, chair         | 500, 150           | 
|------------------|----------------------|--------------------|--------------------|

我一直在看有关使用GROUP_CONCAT或CROSS APPLY或SWITCH STATEMENT的帖子

例如GROUP_CONCAT:

select *, GROUP_CONCAT(`table`.`categoryid` ORDER BY `table`.`categoryid` ASC SEPARATOR ', ') AS `categoryid`
from `table` 
GROUP BY `table`.`requestid`

但是这会将所有内容整合到一个不是由类别ID分隔的列中,而是将所有类别ID放在一列中。

任何建议或帮助将不胜感激。

mysql switch-statement group-concat cross-apply
2个回答
0
投票

谢谢大家的帮助!我没有使用数据透视表就搞清楚了

选择table.requestid AS request_id,group_concat((情况下(table.categoryid = 2)然后table.item结束)separator',')AS item2,group_concat((情况下(table.categoryid = 2)然后table.descriptor结束)separator',')AS descriptor2,group_concat((情况下(table.categoryid = 2)然后table.amount结束)separator',')AS amount2,group_concat((情况下(table.categoryid = 3)然后tableitem end)separator',')AS item3,group_concat((case when(table.categoryid = 3)then table.descriptor end)separator',')AS descriptor3,group_concat((case when(table.categoryid = 3)then table.amount end)separator',')AS amount3 group_concat((case when(table.categoryid = 4)then table.item end)separator',')AS item4,group_concat((case when(table.categoryid = 4)然后table.descriptor结束)分隔符',')AS descriptor4,group_concat((情况下(table.categoryid = 4)然后table.amount结束)separato r',')AS amount4 group_concat((情况下(table.categoryid = 5)然后table.item结束)分隔符',')AS item5,group_concat((情况下(table.categoryid = 5)然后table.descriptor结束)separator',')AS descriptor5,group_concat((情况下(table.categoryid = 5)然后table.amount结束)separator',')AS amount5

来自table

其中((table.categoryid = 2)或(table.categoryid = 3)或(table.categoryid = 4)或(table.categoryid = 5))

table.requestid组成的小组


0
投票

如果类别是固定的(3,4和5),您可以使用此查询:

select 
reqid,
group_concat(distinct if(catid = 3, itemid, null)) as catid3itemid, 
group_concat(distinct if(catid = 3, item, null)) as catid3item, 
group_concat(distinct if(catid = 3, `desc`, null)) as catid3desc, 
group_concat(distinct if(catid = 3, amount, null)) as catid3amount , 
group_concat(distinct if(catid = 4, itemid, null)) as catid4itemid, 
group_concat(distinct if(catid = 4, item, null)) as catid4item, 
group_concat(distinct if(catid = 4, `desc`, null)) as catid4desc, 
group_concat(distinct if(catid = 4, amount, null)) as catid4amount , 
group_concat(distinct if(catid = 5, itemid, null)) as catid5itemid, 
group_concat(distinct if(catid = 5, item, null)) as catid5item, 
group_concat(distinct if(catid = 5, `desc`, null)) as catid5desc, 
group_concat(distinct if(catid = 5, amount, null)) as catid5amount 
from tab 
group by reqid;

如果必须是动态的,则可以使用程序。下面我使用了一个重复结构来生成一个查询,该查询返回每个catid(最小到最大)的所需结构,并使用prepared statment执行它:

-- only to avoid problem with only_full_group_by
set global sql_mode = "";

create table tab (reqid int, catid int, itemid int, item varchar(10), `desc` varchar(20), amount int);
insert into tab values
(1, 3, 16, 'food', 'food', 200),
(1, 3, 17, 'water', 'wtr', 50),
(1, 3, 18, 'film', 'film', 20),
(1, 5, 30, 'room', 'room', 500),
(1, 5, 31, 'chair', 'chair', 150),
(2, 3, 16, 'food', 'food', 200),
(2, 3, 17, 'water', 'wtr', 50),
(3, 3, 18, 'film', 'film', 20),
(3, 5, 30, 'room', 'room', 500),
(3, 5, 31, 'chair', 'chair', 150);

delimiter $$
CREATE PROCEDURE result()
BEGIN

    DECLARE i INT DEFAULT (select min(catid) from tab);
    DECLARE iEnd INT DEFAULT (select max(catid) from tab);

    SET @sQuery = 'select reqid';

    WHILE i <= iEnd DO

        set @sQuery = CONCAT(@sQuery, 
            ', group_concat(distinct if(catid = ',i,', itemid, null)) as catid',i,'itemid,
            group_concat(distinct if(catid = ',i,', item, null)) as catid',i,'item, 
            group_concat(distinct if(catid = ',i,', `desc`, null)) as catid',i,'desc, 
            group_concat(distinct if(catid = ',i,', amount, null)) as catid',i,'amount'
        );

        SET i = i + 1;
    END WHILE; 

    SET @sQuery = CONCAT(@sQuery, ' from tab group by reqid');

    PREPARE stmt FROM @sQuery;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;

END $$


call result();

注意:因为您没有提供太多详细信息,并且在评论中已经说过,所以在应用程序中执行显示逻辑可能更好。

© www.soinside.com 2019 - 2024. All rights reserved.