使用SQL平均分配对象

时间:2017-02-01 02:24:09

标签: sql oracle

我的数据如下

|Fruit   |Numbers|
|Apples  |     50|
|Banana  |     30|
|Oranges |     20|
|Grapes  |    100|
|Peach   |     30|
|Kiwi    |     70|

我需要重新安排3袋,这样我就可以使用NTILE 3袋相同(或几乎)数量的水果。你能帮忙吗?

输出应该像

|Bag_id|Contents        |Count
|Bag 1 | Apples,Oranges,Peaches|100|
|Bag 2 | Kiwi,Banana    |100|
|Bag 3 |Grapes|100|

3 个答案:

答案 0 :(得分:1)

SELECT
  i.*,
  CASE WHEN item <= 3 THEN item ELSE 7 - item END  AS bag
FROM
(
  SELECT
    b.*,
    ROW_NUMBER() OVER (PARTITION BY batch, ORDER BY numbers) AS item
  FROM
  (
    SELECT
      t.*,
      NTILE(6) OVER (ORDER BY numbers) AS batch
    FROM
      your_table t
  )
    b
)
  i

我在手机上,所以我不会添加戈登所做的一点来将这些项目连接成一行。

但这实现了一种非常简单的装袋算法。

当你有6件物品放入3袋时,它恰好相当不错。

当你将4件物品装入3袋时,它确实很糟糕。

它并没有真正处理大量的小数字和少量的大数字。

Google为您提供了许多算法,并选择您的偏好。

但这是一个例子,使用NTILE ......

答案 1 :(得分:0)

如果您只想在每个购物篮中放两个水果(忽略numbers列),那么您可以使用ntile()

select 'Bag ' || tercile,
       listagg(Fruit, ',') over (within group order by Fruit) as fruits
from (select t.*,
             ntile(3) over (order by numbers) as tercile
      from t
     ) t
group by tercile;

与您的示例结果一样,numbers的总和在整个篮子中甚至不大致相同。

答案 2 :(得分:0)

我有~300个水果,所以基于@MatBailie,我找到了溶液。

谢谢大家!!

选择 Wm_concat (果实),

FROM(SELECT也就是
CASE
WHEN项&lt; = 10 THEN项
ELSE 10 - 项目
END AS袋
FROM(SELECT湾

ROW_NUMBER ()
OVER(
分区分批
ORDER BY CNT)AS项目
FROM(SELECT吨。*,
NTILE (50)
OVER(
ORDER BY CNT)批处理
从TMP中T)B)ⅰ)
GROUP BY袋;