Распределение последовательных результатов SQL равномерно по количеству - PullRequest
0 голосов
/ 28 сентября 2018

У меня есть результаты SQL, которые мне нужно разбить на диапазоны элементов, и количество распределено равномерно по ряду задач.Какой хороший способ сделать это?

Мои данные выглядят так.

+------+-------+----------+
| Item | Count | ItmGroup |
+------+-------+----------+
| 1A   |   100 |        1 |
| 1B   |    25 |        1 |
| 1C   |     2 |        1 |
| 1D   |     6 |        1 |
| 2A   |    88 |        2 |
| 2B   |    10 |        2 |
| 2C   |   122 |        2 |
| 2D   |    12 |        2 |
| 3A   |     4 |        3 |
| 3B   |   103 |        3 |
| 3C   |     1 |        3 |
| 3D   |    22 |        3 |
| 4A   |    55 |        4 |
| 4B   |    42 |        4 |
| 4C   |   100 |        4 |
| 4D   |     1 |        4 |
+------+-------+----------+

Item = код товара.Count = этот контекст определяет популярность товара.Это может быть использовано для ранга предметов, если это будет необходимо.ItmGroup - это родительское значение для столбца Itm.Элемент содержится в группе.

Что отличает это от других подобных вопросов, которые я видел, так это то, что диапазоны, которые мне нужно определить, не могут быть взяты из порядка, который они показывают в этой таблице.Мы можем сделать Range Item от A1 до B3, другими словами, они могут пересекать ItmGroups, но они должны оставаться в алфавитно-цифровом порядке по Item.

Ожидаемым результатом будут диапазоны элементов, которые равномерно распределяют общее количество.

+------+-------+----------+
| FrItem | ToItem | TotCount|
+------+-------+----------+
| 1A   |   2D  |      134 |
| 3A   |   3D  |      130 |
(etc)

Ответы [ 2 ]

0 голосов
/ 28 сентября 2018

То же, что и принятый ответ, за исключением объявления номера партии и добавления к оператору выбора в WITH cumulativeCte для предотвращения остатка.

  DECLARE @BatchCount NUMERIC(4,2) = 5.00;

    WITH
      cumulativeCte AS
    (
      SELECT
        *,
        SUM(r.[Count]) OVER (ORDER BY Item)   AS cumulativeCount,
        SUM(r.[Count]) OVER ()                AS totalCount
        ,CEILING(SUM(r.[Count]) OVER (ORDER BY IM.MMITNO ASC) / (SUM(r.[Count]) OVER () / @BatchCount)) AS BatchNo
      FROM
        records r
    )
    SELECT
      MIN(c.Item)    AS frItem,
      MAX(c.Item)    AS toItem,
      SUM(c.[Count]) AS TotCount,
      c.BatchNo

    FROM
      cumulativeCte c
    GROUP BY
      c.BatchNo
    ORDER BY
      c.BatchNo
0 голосов
/ 28 сентября 2018

Если вы довольны приблизительной оценкой, это разделит данные на две группы.

В первой группе всегда будет как можно больше записей, но не болеечем половина от общего количества (а у группы 2 будет остаток) .

WITH
  cumulative AS
(
  SELECT
    *,
    SUM([Count]) OVER (ORDER BY Item)   AS cumulativeCount,
    SUM([Count]) OVER ()                AS totalCount
  FROM
    yourData
)
SELECT
  MIN(item)    AS frItem,
  MAX(item)    AS toItem,
  SUM([Count]) AS TotCount
FROM
  cumulative
GROUP BY
  CASE WHEN cumulativeCount <= totalCount / 2 THEN 0 ELSE 1 END
ORDER BY
  CASE WHEN cumulativeCount <= totalCount / 2 THEN 0 ELSE 1 END

Разделить данные на 5 частей, это похоже ...

GROUP BY
  CASE WHEN cumulativeCount <= totalCount * 1/5 THEN 0
       WHEN cumulativeCount <= totalCount * 2/5 THEN 1
       WHEN cumulativeCount <= totalCount * 3/5 THEN 2
       WHEN cumulativeCount <= totalCount * 4/5 THEN 3
                                                ELSE 4 END

В зависимости от ваших данных это не обязательно идеально.

 Item | Count       GroupAsDefinedAbove   IdealGroup
------+-------
  1A  |   4              1                  1
  2A  |   5              2                  1
  3A  |   8              2                  2

Если вы хотите что-то, что может сделать две группы как можно более близкими по размеру, это намного большекомплекс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...