Установите переменную в SQL и используйте эту переменную, чтобы выяснить, сколько блоков необходимо для размещения списка элементов с учетом их размеров. - PullRequest
0 голосов
/ 08 ноября 2019

Я пытаюсь создать SQL-запрос, где, учитывая список предметов, я выясняю, сколько ящиков (коробок) мне нужно, чтобы уместить все предметы.

В моем сценарии есть два типа предметов. CA предметов и PG предметов. CA обозначает коробки и представляет собой элементы, которые уже собраны, в заранее упакованных коробках, заполненных элементами, которые вы не должны открывать. Таким образом, один элемент CA = один ящик на общее количество ящиков. Элементы PG - это отдельные элементы, и это в значительной степени является основой всего запроса. Таким образом, элементы CA поставляются в виде уже упакованных коробок, но элементы PG сами являются фактическими элементами, и цель состоит в том, чтобы подсчитать, сколько картонных коробок необходимо для упаковки всех элементов PG.

Я кодировал то, что я ищу, в psuedocode, но я не уверен, как превратить это в реальный код.

DECLARE @TotalWeightVar int
DECLARE @TotalFeetVar int
DECLARE @CartonMaxVolume int
DECLARE @CartonMaxWeight int

SET @TotalWeightVar = 0
SET @TotalFeetVar = 0
SET @CartonMaxVolume = 0
SET @CartonMaxWeight = 0

SELECT T.Cust_Po,

    ISNULL(SUM (T.TWEIGHT), '0') TotalWeight,

    ISNULL(cast((SUM (T.TFEET)) as numeric(9,2)), '0' ) TotalFeet,

    SET @TotalWeightVar = SUM (CASE WHEN T.PROD_UDF4 = 'PG' THEN T.TWEIGHT END )
    SET @TotalFeetVar = SUM (CASE WHEN T.PROD_UDF4 = 'PG' THEN T.TFEET END )
    SET @CartonMaxVolume = 480
    SET @CartonMaxWeight = 40

    -- I need it to calculate both the CA half the PG half and then add them together, is this the way to do it? 
    SUM (
        -- If it's a CA item we just count the quantity of the item as the amount of Cartons needed.
        CASE WHEN T.PROD_UDF4 = 'CA' 
            THEN T.QTY_ORIGNL
        --Then we count the total amount of cartons needed to fit all the PG items. 
        ELSE 
            CASE WHEN T.PROD_UDF4 = 'PG' 
            -- if the total weight is not greater than the carton max weight and the total cube fits inside one carton
                CASE WHEN @TotalWeightVar < @CartonMaxWeight AND @TotalFeetVar < @CartonMaxVolume
    --              -- use one carton
                    THEN 1
                ELSE
                -- take the max of (total weight / carton max weight) OR (total volume / max carton volume)
                MAX( @TotalWeightVar / @CartonMaxWeight AND @TotalFeetVar / @CartonMaxVolume)
            END
        END
    ) TotalCartons


FROM (

Select

    Purchase_Order_Number,
    d.PRODUCT,

    d.QTY_ORIGNL,

    c.WEIGHT,
    c.LENGTH,
    c.WIDTH,
    c.HEIGHT,

    CASE WHEN 
        c.WEIGHT is NULL 
            THEN NULL 
        ELSE
            (c.WEIGHT*d.QTY_ORIGNL)
        END TWEIGHT,

    CASE 
    WHEN c.LENGTH is NULL or c.WIDTH is NULL or c.HEIGHT is NULL 
            THEN NULL 
        ELSE 
            (((c.LENGTH*c.WIDTH*c.HEIGHT)/1728)*d.QTY_ORIGNL)
        END TFEET,

    s.PROD_UDF4

    From Tables

    where P.Purchase_Order_Number=  @PO OR @PO is NULL


) T

GROUP BY Purchase_Order_Number

Внутренний запрос прост, это просто список продуктов с их типом и размерами. Затем я вычисляю общий вес продукта и общий куб продукта, используя его количество.

Вот пример результата внутреннего запроса:

+--------------------+------------+--------+--------+-------+--------+---------+----------+-----------+
|      PRODUCT       | QTY_ORIGNL | WEIGHT | LENGTH | WIDTH | HEIGHT | TWEIGHT |  TFEET   | PROD_UDF4 |
+--------------------+------------+--------+--------+-------+--------+---------+----------+-----------+
| 18SP700002XBC00700 |          2 |      2 |     21 |    10 | 1      |       4 | 0.243054 | PG        |
| 1812340024B00604   |          1 |     16 |     18 |    15 | 7      |      16 | 1.09375  | CA        |
| 18SP700002MBC00700 |          4 |      2 |     21 |    15 | 1.5    |       8 | 1.093748 | PG        |
| 18SP700002SBC00700 |          2 |      1 |     20 |     9 | 1      |       2 | 0.208332 | PG        |
| 18SP700002LBC00700 |          4 |      2 |     21 |     9 | 1      |       8 | 0.4375   | PG        |
+--------------------+------------+--------+--------+-------+--------+---------+----------+-----------+

А теперь я должен взять эти предметы и их размеры и выяснить, сколько коробок потребуется дляупаковать всеЦентры сертификации уже являются упакованными коробками, поэтому никаких расчетов там не требуется. Мне нужно взять предметы PG и, используя вес и ноги предметов, найти минимальное количество необходимых коробок.

Также, пожалуйста, скажите мне, если я поступаю неправильно. Я пытаюсь понять это по ходу дела.

Ответы [ 2 ]

0 голосов
/ 08 ноября 2019

Я думаю, что вам просто не хватает слоя агрегации в вашем псевдокоде. Хотя я совсем не уверен, что это механизм определения того, сколько коробок необходимо в реальном мире, я доверяю вашей логике, что это работает для вашего варианта использования.

declare @CartonMaxVolume int = 480;
declare @CartonMaxWeight int = 40;

select
    Cust_Po,
    (
        CaCartons
        + case
            when PgWeight < @CartonMaxWeight and PgFeet < @CartonMaxVolume
                then 1
            when PgWeight / @CartonMaxWeight >= PgFeet / @CartonMaxVolume
                then PgWeight / @CartonMaxWeight
            else
                PgFeet / @CartonMaxVolume
        end
    ) TotalCartons
from
    (
        select
            T.Cust_Po,
            isnull(sum (T.TWEIGHT), '0') TotalWeight,
            isnull(cast((sum (T.TFEET)) as numeric(9,2)), '0' ) TotalFeet,
            sum(case when PROD_UDF4 = 'CA' then 1 end) CaCartons,
            sum(case when PROD_UDF4 = 'PG' then TWEIGHT end) PgWeight,
            sum(case when PROD_UDF4 = 'PG' then TFEET end) PgWeight
        from
            (
                select
                    Purchase_Order_Number,
                    d.PRODUCT,
                    d.QTY_ORIGNL,
                    c.WEIGHT,
                    c.LENGTH,
                    c.WIDTH,
                    c.HEIGHT,
                    case
                        when c.WEIGHT is null
                            THEN null 
                        else 
                            c.WEIGHT * d.QTY_ORIGNL
                    end TWEIGHT,
                    case 
                        when c.LENGTH is null or c.WIDTH is null or c.HEIGHT is null 
                            THEN null 
                        else 
                            ((c.LENGTH * c.WIDTH * c.HEIGHT) / 1728) * d.QTY_ORIGNL
                    end TFEET,
                    s.PROD_UDF4
                from
                    Tables
                where
                    P.Purchase_Order_Number = @PO 
                    or @PO is null
            ) T
        group by
            Purchase_Order_Number
    ) PurchaseOrder
0 голосов
/ 08 ноября 2019

Это напоминает мне о «проблеме ранца», которая, вообще говоря, очень сложная проблема, которую нужно решить алгоритмически. Я предполагаю, что Transact SQL - не лучший инструмент для этого. Ссылка говорит о проблеме ранца

...