SQL-запрос, чтобы разделить Порядок количеств продукта по определенному постоянному пороговому количеству? - PullRequest
2 голосов
/ 11 апреля 2019

Есть список товаров с количествами.Каждое количество продукта должно быть разделено на определенное постоянное количество.

Я пробовал с данным списком, если количество продукта больше, чем постоянное количество, результат в порядке.Когда количество продукта меньше константы, я не могу вывести логику.Постоянное количество товара составляет 650

SortOrder   ProductCode Quantity
1           PC1         1400
2           PC2         4500
3           PC3         1500

Приведенный ниже код отлично работает для этого списка.

SortOrder   ProductID   Quantity
1           PC1         650
1           PC1         650
1           PC1         100
2           PC2         550
2           PC2         650
2           PC2         650
2           PC2         650
2           PC2         650
2           PC2         650
2           PC2         650
2           PC2         50
3           PC3         600
3           PC3         650
3           PC3         250

Но проблема в том, что количество товара меньше, чем постоянное значение.

SortOrder   ProductCode Quantity
1           PC1         400
2           PC2         500
3           PC3         1300
4           PC4         300
5           PC5         500

Результат должен быть

SortOrder   ProductCode Quantity    Shift
1           PC1         400         A
2           PC2         250         A
2           PC2         250         B
3           PC3         400         B
3           PC3         650         C
3           PC3         250         A
4           PC4         300         A
5           PC5         100         A
5           PC5         400         B

Сумма каждого сдвига должна равняться постоянному значению

Пожалуйста, помогите мне в этом.

Ответы [ 2 ]

1 голос
/ 11 апреля 2019

Я протестировал его с обоими образцами и получил ожидаемый результат, я использовал рекурсивный CTE для получения величины компенсации, дайте мне знать, если вы хотите, чтобы я написал более подробное объяснение определенной части кода.

DECLARE @Const INT = 650

;WITH nums AS (
    SELECT 1 as num
    UNION ALL
    SELECT num + 1 FROM nums WHERE num < 100
), compensation AS (
    SELECT *, 0 as Compensation, SortOrder as OD
    FROM #Temp_ProductQtyOrderList t
    WHERE SortOrder = 1
    UNION ALL
    SELECT t.*, CASE WHEN c.Quantity - Compensation < 0 THEN ABS(c.Quantity - Compensation) ELSE @Const - ((c.Quantity - Compensation)%@const) END, 
    CASE WHEN c.Quantity - Compensation < 0 THEN c.OD ELSE c.SortOrder END
    FROM #Temp_ProductQtyOrderList t
    JOIN compensation C ON c.SortOrder = t.SortOrder - 1 

), split1 AS (
    SELECT CASE compensation WHEN 0 THEN 0 ELSE 1 END + num rn, b.*, t.SortOrder as OD
    FROM compensation t
    CROSS APPLY (
        VALUES(t.SortOrder, t.ProductID, @const)
    ) b (SortOrder, ProductCode, Quantity)
    join nums ON num <= (t.Quantity-compensation)/@const
    UNION ALL
    SELECT 1, t.SortOrder, t.ProductID, CASE WHEN Quantity > compensation THEN compensation ELSE Quantity END, OD
    FROM compensation t
    WHERE compensation > 0
    UNION ALL
    SELECT CASE compensation WHEN 0 THEN 0 ELSE 1 END + (t.Quantity-compensation)/@const + 1, t.SortOrder, t.ProductID, (t.Quantity-compensation)%@const, sortorder
    FROM compensation t
    WHERE (t.Quantity-compensation)%@const > 0
)
SELECT SortOrder, RN, ProductCode, Quantity, CHAR(64 + DENSE_RANK() OVER (ORDER BY OD, CASE WHEN Quantity<@Const OR SortOrder<> OD THEN 999 ELSE rn END)) Shift
FROM split1
ORDER BY SortOrder, rn, ProductCode

PS Ваш собственный образец не соответствует вашему требованию:

сумма каждой смены должна быть равна постоянному значению

Я не нашел разумных критериев для повторения сдвигов A и B, поэтому он вернет сдвиги A, B, C, D и E для этого образца ввода ...

0 голосов
/ 11 апреля 2019
DECLARE @const INT = 650;

SELECT       sortorder
           , productid
           , c.val
  FROM       #Temp_ProductQtyOrderList   AS l
 CROSS APPLY (   SELECT ROW_NUMBER() OVER (ORDER BY o.object_id) AS m
                   FROM sys.all_objects o
                   ) AS mult
 CROSS APPLY (SELECT quantity / (mult.m * @const) AS val) AS a
 CROSS APPLY (   SELECT CASE WHEN quantity < @const THEN quantity
                             WHEN val = 0 THEN quantity - @const * (mult.m - 1)
                             ELSE @const
                        END AS val) AS c
 WHERE       mult.m <= quantity / @const + 1 AND c.val > 0;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...