【问题标题】:MySQL - multi-row by 1 id & converting multi-column data into a comma delimited rowMySQL - 1 个 id 的多行 & 将多列数据转换为逗号分隔的行
【发布时间】:2019-07-28 15:09:17
【问题描述】:

我有一个数据库表:
分隔每个请求的请求人 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 放在一列中。

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

【问题讨论】:

  • 您需要旋转表格以将每个类别放入自己的一组列中。
  • 对不起,我对编码很陌生,所以我一直在尝试在论坛上搜索答案,但没有什么真正适合的,所以请耐心等待我缺乏知识。有没有办法在查询中使用关于 IF categoryid = 1 的 IF 语句 THEN group_concat 同一 requestid 中 categoryid = 1 的所有内容都用逗号分隔列 item、descriptor 和 amount?
  • 是的,您可以在 group_concat 中使用 if 但是,如果要在应用程序中显示,我建议在应用程序代码中完成,正如@Strawberry 所建议的那样。无论如何,我会发布一个关于如何使用 sql 的更完整的答案。

标签: mysql switch-statement group-concat cross-apply


【解决方案1】:

谢谢大家的帮助!我没有使用数据透视表就知道了

选择table.requestid AS request_id, group_concat((当 (table.categoryid = 2) 然后table.item end) 分隔符',') AS item2 ,group_concat((当 (table.categoryid = 2) 然后table.descriptor end) 分隔符',') AS descriptor2, group_concat((当 (table.categoryid = 2) 然后table.amount end) 分隔符',') AS amount2, group_concat((当 (table.categoryid = 3) 然后table.item end) 分隔符',') AS item3, group_concat((当 (table.categoryid = 3) 然后table.descriptor end) 分隔符',') AS descriptor3, group_concat((当 (table.categoryid = 3) 然后table.amount end) 分隔符',') AS amount3 group_concat((当 (table.categoryid = 4) 然后table.item end) 分隔符',') AS item4, group_concat((当 (table.categoryid = 4) 然后table.descriptor end) 分隔符',') AS descriptor4, group_concat((当 (table.categoryid = 4) 然后table.amount end) 分隔符',') AS amount4 group_concat((当 (table.categoryid = 5) 然后table.item end) 分隔符',') AS item5, group_concat((当 (table.categoryid = 5) 然后table.descriptor end) 分隔符',') AS descriptor5, group_concat((当 (table.categoryid = 5) 然后table.amount end) 分隔符',') AS amount5

来自table

在哪里 ((table.categoryid = 2) 或 (table.categoryid = 3) 或 (table.categoryid = 4) 或 (table.categoryid = 5))

table.requestid分组

【讨论】:

    【解决方案2】:

    如果类别是固定的(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();
    


    注意:因为您没有提供太多细节,并且正如 cmets 中已经说过的那样,在应用程序中执行显示逻辑可能会更好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-07
      • 2018-11-02
      • 2016-01-29
      • 2018-04-13
      • 2012-02-01
      相关资源
      最近更新 更多