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

虽然这在实践中有效,但不能保证有效,因为 MySQL 不保证select语句中列评估的顺序(因此理论上@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;

后两者应该比第一个解决方案减少更多空间。

于 2013-07-07T23:31:31.463 回答