0

データセットの残りの部分で同じであることがわかっている値を NULL にする方法はありますか?

mysql> SELECT
    -> `p1`.`id`,
    -> `p1`.`name`,
    -> `pp1`.`name` `product_property_name`,
    -> `pp1`.`value` `product_property_name`
    -> FROM
    -> `product` `p1`
    -> INNER JOIN
    -> `product_property` `pp1`
    -> ON
    -> `p1`.`id` = `pp1`.`product_id`;
+----+------+-----------------------+-----------------------+
| id | name | product_property_name | product_property_name |
+----+------+-----------------------+-----------------------+
|  1 | Tar  | foo                   | bar                   |
|  1 | Tar  | foo1                  | bar1                  |
|  1 | Tar  | foo2                  | bar2                  |
|  2 | Qaz  | too                   | doo                   |
|  2 | Qaz  | too1                  | doo1                  |
+----+------+-----------------------+-----------------------+
5 rows in set (0.00 sec)

この場合、 withproductのために複数回返されます。結果をグループ化するには、すべての製品の最初の行のみが必要です。INNER JOINproduct_property

したがって、目的の出力:

+----+------+-----------------------+-----------------------+
| id | name | product_property_name | product_property_name |
+----+------+-----------------------+-----------------------+
|  1 | Tar  | foo                   | bar                   |
|  1 | NULL | foo1                  | bar1                  |
|  1 | NULL | foo2                  | bar2                  |
|  2 | Qaz  | too                   | doo                   |
|  2 | NULL | too1                  | doo1                  |
+----+------+-----------------------+-----------------------+

これにより、特にメモリ使用率を大幅に削減できます。大規模なデータセットをグループ化する場合。

4

1 に答える 1

0

変数を使用して、必要なことを実行できます。

SELECT `p1`.`id`,
       (case when name <> @prevname then `p1`.`name` end) as name,
       `pp1`.`name` as `product_property_name`,
       `pp1`.`value` as `product_property_name`,
       @prevname := name
FROM `product` `p1` INNER JOIN
     `product_property` `pp1` cross join
     (select @prevname := '') const
     ON `p1`.`id` = `pp1`.`product_id`;

selectこれは実際には機能しますが、MySQL はステートメント内の列の評価の順序を保証しないため (理論的には、@prevname := name最初に発生する可能性があります)、機能することは保証されません。

ただし、group_concat()代わりに使用して、プロパティごとに複数の行を省略することを検討することもできます。

SELECT `p1`.`id`,
       `p1`.`name`,
       group_concat(pp1.name, ', ') as product_property_names,
       group_concat(pp1.value, ', ') as product_property_values
FROM `product` `p1` INNER JOIN
     `product_property` `pp1`
     ON `p1`.`id` = `pp1`.`product_id`
group by p1.id, p1.name;

または、単一のペアとして:

SELECT `p1`.`id`,
       `p1`.`name`,
       group_concat(concat(pp1.name, '=', pp1.value), '; ') as product_property_pairs
FROM `product` `p1` INNER JOIN
     `product_property` `pp1`
     ON `p1`.`id` = `pp1`.`product_id`
group by p1.id, p1.name;

後者の 2 つは、最初のソリューションよりもスペースを削減する必要があります。

于 2013-07-07T23:31:31.463 に答える