0

我正在处理产品数据提要,目前正在对相关产品进行分组。我几乎得到了我想要的东西,但是,就像一个平庸的赛车手,我在最需要的时候已经用尽了技巧。

为了说明我的问题,我创建了一个简化版本。下面是数据结构:

CREATE TABLE `feed` (
    `sku` VARCHAR(10),
    `price` DECIMAL(6,2),
    `groupkey` VARCHAR(10)
  );

INSERT INTO `feed` (`sku`, `price`, `groupkey`) VALUES
('AAA', 10.00, NULL),
('BBB', 10.00, 'group1'),
('CCC', 12.00, 'group1'),
('DDD', 10.00, 'group2'),
('EEE', 12.00, 'group2'),
('FFF', 14.00, 'group2'),
('GGG', 20.00, NULL);

我目前的查询是:

SELECT feed.groupkey
    , group_concat(feed.sku) AS skus
    , group_concat(feed.price) AS prices
    , feed.price AS pprice
FROM
    feed
WHERE
    feed.groupkey IS NOT NULL
GROUP BY
    feed.groupkey;

该查询返回以下行:

+----------+-------------+-------------------+--------+
| groupkey | skus        | prices            | pprice |
+----------+-------------+-------------------+--------+
| group1   | BBB,CCC     | 10.00,12.00       |  10.00 |
| group2   | DDD,EEE,FFF | 10.00,12.00,14.00 |  10.00 |
+----------+-------------+-------------------+--------+

我真正需要做的是pprice从每个 concatenated中减去price,给我每个 sku 之间的价格差异,而不是它们的绝对价格。这将返回梦想的结果:

+----------+-------------+-------------------+--------+
| groupkey | skus        | prices            | pprice |
+----------+-------------+-------------------+--------+
| group1   | BBB,CCC     | 0.00,2.00         |  10.00 |
| group2   | DDD,EEE,FFF | 0.00,2.00,4.00    |  10.00 |
+----------+-------------+-------------------+--------+

总的来说,我在这个提要上花了很多时间,并且真的被困在可能是集成中的最后一个障碍上。我真的很感激一些指导,以帮助我朝着正确的方向前进。

编辑:我将此查询的结果用作“虚拟”产品行,作为组中产品的父级。

4

1 回答 1

3

您可以在group_concat(), 中进行减法运算,例如:

SELECT feed.groupkey, group_concat(feed.sku) AS skus,
       group_concat(feed.price - min(feed.price)) AS prices
       min(feed.price) AS pprice
FROM feed
WHERE feed.groupkey IS NOT NULL
GROUP BY feed.groupkey

问题是 。. . 哪个饲料价格?原始查询中返回的值是组中某一行的任意值。考虑到您可能想要最小值的差异,我使用了该值。

我认为编写查询的最佳方法是:

SELECT feed.groupkey, group_concat(feed.sku) AS skus,
       group_concat(feed.price - fsum.minprice) AS prices
       min(feed.price) AS pprice
FROM feed left outer join
     (select groupkey, MIN(feed.price) as minprice
      from feed
      group by groupkey
     ) fsum
     on feed.groupkey = fsum.groupkey
WHERE feed.groupkey IS NOT NULL
GROUP BY feed.groupkey

不能假设隐藏列和group_concat(). 文档在这一点上非常明确:

MySQL extends the use of GROUP BY so that the select list can refer to nonaggregated columns not named in the GROUP BY clause. This means that the preceding query is legal in MySQL. You can use this feature to get better performance by avoiding unnecessary column sorting and grouping. However, this is useful primarily when all values in each nonaggregated column not named in the GROUP BY are the same for each group. The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate. Furthermore, the selection of values from each group cannot be influenced by adding an ORDER BY clause. Sorting of the result set occurs after values have been chosen, and ORDER BY does not affect which values the server chooses.

If you want things in a particular order, then you need to be sure the structure is queried properly. That said, it often works in practice, but there is no guarantee.

于 2013-03-05T19:00:47.187 回答