简体   繁体   English

MySQL-多行乘以1的ID并将多列数据转换为逗号分隔的行

[英]MySQL - multi-row by 1 id & converting multi-column data into a comma delimited row

I have a database table: 我有一个数据库表:
requesting persons ID column that separates each request (reqid) 分隔每个请求的请求者ID列(需要)
category ID column that separates into different categories each item that's in the request (catid) 类别ID列,可将请求中的每个项目(类别)分为不同的类别
an item ID column that separates each item type within the category (itemid) 一个商品ID列,用于分隔类别(itemid)中的每个商品类型
an item name column that lists the name of the item (item) 列出项目名称(项目)的项目名称列
an item descriptor column that gives a description of the item (desc) 提供项目描述的项目描述符列(desc)
and amount column that gives the total cost of each item in that category (amount) 和金额列,给出该类别中每个项目的总费用(金额)

so my table looks like this: 所以我的桌子看起来像这样:

|---------|-------|----------|--------|-------|------------|
|  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        | 
|---------|-------|----------|--------|-------|------------|

And i want my query result to look like 我希望我的查询结果看起来像

|--------|------------------|----------------------|--------------------|--------------------|
| 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                 | 
|--------|------------------|----------------------|--------------------|--------------------|

continued: 继续:

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

continued final: 继续决赛:

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

I've been seeing posts about using GROUP_CONCAT or CROSS APPLY or SWITCH STATEMENT 我一直在看有关使用GROUP_CONCAT或CROSS APPLY或SWITCH STATEMENT的帖子

For instance GROUP_CONCAT: 例如GROUP_CONCAT:

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

but this lumps everything into a column not separated by the category id , but all the category ids together in one column. 但这会将所有内容集中到一列,而不是由类别ID分隔,而是将所有类别ID合并到一列中。

Any suggestions or help would be much appreciated. 任何建议或帮助将不胜感激。

thank you all for the help! 谢谢大家的帮助! i figured it out without using pivot tables 我没有使用数据透视表就知道了

select table . 选择table requestid AS request_id , group_concat((case when ( table . categoryid = 2) then table . item end) separator ',') AS item2 ,group_concat((case when ( table . categoryid = 2) then table . descriptor end) separator ',') AS descriptor2 , group_concat((case when ( table . categoryid = 2) then table . amount end) separator ',') AS amount2 , group_concat((case when ( table . categoryid = 3) then table . item 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) then table . descriptor end) separator ',') AS descriptor4 , group_concat((case when ( table . categoryid = 4) then table . amount end) separator ',') AS amount4 group_concat((case when ( table . categoryid requestid AS request_id ,GROUP_CONCAT((情况下( tablecategoryid = 2),那么tableitem端)分离器”, ')AS item2 ,GROUP_CONCAT((情况下( tablecategoryid = 2),那么tabledescriptor端)分隔符' , ')AS descriptor2 ,GROUP_CONCAT((情况下( tablecategoryid = 2),那么tableamount端)分离器',“)AS amount2 ,GROUP_CONCAT((情况下( tablecategoryid = 3),那么tableitem端)分离器' ')AS item3 ,GROUP_CONCAT((情况下( tablecategoryid = 3),那么tabledescriptor端)分离器',')AS descriptor3 ,GROUP_CONCAT((情况下( tablecategoryid = 3),那么tableamount端)分离器' ')AS amount3 GROUP_CONCAT((情况下( tablecategoryid = 4),那么tableitem端)分离器',')AS item4 ,GROUP_CONCAT((情况下( tablecategoryid = 4),那么tabledescriptor端)分离器' ')AS descriptor4 ,GROUP_CONCAT((情况下( tablecategoryid = 4),那么tableamount端)分离器',')AS amount4 GROUP_CONCAT((情况下( tablecategoryid categoryid = 5) then table . categoryid = 5)然后是table item end) separator ',') AS item5 , group_concat((case when ( table . categoryid = 5) then table . descriptor end) separator ',') AS descriptor5 , group_concat((case when ( table . categoryid = 5) then table . amount end) separator ',') AS amount5 item端)分离器' ')AS item5 ,GROUP_CONCAT((情况下( tablecategoryid = 5),则tabledescriptor端)分离器',')AS descriptor5 ,GROUP_CONCAT((情况下( tablecategoryid = 5),然后tableamount端)分离器'')AS amount5

from table table

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

group by table . table分组。 requestid

If the categories were fixed (3, 4 and 5) you could use this query: 如果类别是固定的(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;


If it has to be dynamic, a procedure can be used. 如果必须是动态的,则可以使用过程。 Below I have used a repetition structure to generate a query that returns the desired structure for each catid (minimum to maximum) and executes it with prepared statment : 下面,我使用了重复结构来生成查询,该查询返回每个catid所需的结构(最小到最大)并使用准备好的语句执行它:

-- 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();


Note: Because you did not give too many details and as has already been said in the comments, it might be better to perform the display logic in the application. 注意:因为您没有提供太多详细信息,而且正如注释中所述,所以最好在应用程序中执行显示逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM