1. 程式人生 > >SQL 豎排轉成橫排 並根據屬性分類,合併 mysql的group_concat用法 pgsql的string_agg用法

SQL 豎排轉成橫排 並根據屬性分類,合併 mysql的group_concat用法 pgsql的string_agg用法

工作中遇到一個問題: 產品有許多屬性, 這些屬性並不儲存在產品的基本資訊表中, 而是儲存在屬性表中, 需要根據其中的一些屬性做分頁查詢. 通過查資料, 找到解決方案, 例子如下:

MySQL語句

DROP TABLE IF EXISTS `attribute`;
CREATE TABLE `attribute` (
  `id` int(11) DEFAULT NULL,
  `attr_code` varchar(255) DEFAULT NULL,
  `attr_name` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ---------------------------- -- Records of attribute -- ---------------------------- INSERT INTO `attribute` VALUES ('1', 'productname', '小米'); INSERT INTO `attribute` VALUES ('1', 'productcode', 'xm123456'); INSERT INTO `attribute` VALUES ('1', 'scale', '100萬噸'); INSERT INTO `attribute` VALUES ('2'
, 'productname', '汽車');
INSERT INTO `attribute` VALUES ('2', 'productcode', 'qc632521'); INSERT INTO `attribute` VALUES ('2', 'scale', '100萬輛'); INSERT INTO `attribute` VALUES ('3', 'productname', '電腦'); INSERT INTO `attribute` VALUES ('3', 'productcode', 'dn852963'); INSERT INTO `attribute` VALUES ('3'
, 'scale', '100萬臺');
INSERT INTO `attribute` VALUES ('4', 'productname', '手機'); INSERT INTO `attribute` VALUES ('4', 'productcode', 'sj8524632'); INSERT INTO `attribute` VALUES ('4', 'scale', '100萬部'); INSERT INTO `attribute` VALUES ('1', 'productname', '大米'); INSERT INTO `attribute` VALUES ('1', 'productname', '高粱');

以下為資料插入的結果
這裡寫圖片描述

需求及解決方法

按照id分組, 相同屬性,即attr_code相同的attr_name合併,以”,”隔開.

SELECT
    id,
    group_concat(
        (
            CASE attr_code
            WHEN 'productname' THEN
                attr_name
            ELSE
                NULL
            END
        )
    ) productname,
    max(
        CASE attr_code
        WHEN 'productcode' THEN
            attr_name
        ELSE
            NULL
        END
    ) productcode,
    max(
        CASE attr_code
        WHEN 'scale' THEN
            attr_name
        ELSE
            NULL
        END
    ) scale
FROM
    attribute
GROUP BY
    id;

結果如下,注意紅框所示.
這裡寫圖片描述

下面是pgsql的解決方法, pgsql沒有group_concat, 可以用string_agg解決.

SELECT
    id,
    string_agg (
        (
            CASE attr_code
            WHEN 'productname' THEN
                attr_name
            ELSE
                NULL
            END
        ),
        ","
    ) productname,
    max(
        CASE attr_code
        WHEN 'productcode' THEN
            attr_name
        ELSE
            NULL
        END
    ) productcode,
    max(
        CASE attr_code
        WHEN 'scale' THEN
            attr_name
        ELSE
            NULL
        END
    ) scale
FROM
    attribute
GROUP BY
    id;