Логика SQL для определения непроданных запасов и соответствующих доступных дат (Доступно для продажи) - PullRequest
0 голосов
/ 11 июля 2019

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

В таблице ниже. Столбец +/- представляет еженедельный входящий и исходящий, а доступное количество - это скользящий SUM OVER PARTITION BY столбца +/-. Я смог получить доступное количество по этой простой логике:

Case when Min(X.Qty_Available) > 0 Then Min(X.Qty_Available) else 0 END 
AS Immediate_available_Qty

Таблица:

+-------------+---------------+---------------+------+---------------+
| Item Number |   Item Name   | week_end_date |  +/- | Qty_Available |
+-------------+---------------+---------------+------+---------------+
|      123456 | Fidget Widget | 7/13/2019     |  117 |           117 |
|      123456 | Fidget Widget | 7/20/2019     |   49 |           166 |
|      123456 | Fidget Widget | 7/27/2019     |   -7 |           159 |
|      123456 | Fidget Widget | 8/3/2019      |  -12 |           147 |
|      123456 | Fidget Widget | 8/10/2019     |   -1 |           146 |
|      123456 | Fidget Widget | 8/17/2019     |   45 |           191 |
|      123456 | Fidget Widget | 8/24/2019     |   -1 |           190 |
|      123456 | Fidget Widget | 8/31/2019     |   -1 |           189 |
|      123456 | Fidget Widget | 9/7/2019      |   50 |           239 |
+-------------+---------------+---------------+------+---------------+

Мои желаемые результаты этого запроса будут следующими:

+-----------+-----+
|  Output   | Qty |
+-----------+-----+
| 7/13/2019 | 117 |
| 7/20/2019 |  29 |
| 8/17/2019 |  43 |
+-----------+-----+

вторая доступность определяется путем извлечения первого доступного количества 117 из каждой строки в столбце Qty_Available и нахождения нового минимума. Если новый минимум равен нулю, найдите следующую непрерывно положительную строку данных (которая проходит до самого конца данных). Повторите процедуру для третьего доступного количества и затем остановитесь.

Я думал о том, чтобы следовать логике RCTE, но не хочу погружаться в эту кроличью нору, если есть лучший способ решения этой проблемы, и я даже не уверен, что RCTE работает для этой проблемы?

Ответы [ 2 ]

0 голосов
/ 16 июля 2019

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

Я закончил тем, что запустил это во временную таблицу и изменил закомментированный раздел в таблице "A".затем повторно запустите это во временную таблицу.

Select 
F.Upc,
F.name,
F.Week_end_date as First_Available_Date,
E.Qty_Available_1

From
    (
    Select Distinct 
    D.Upc,
    D.name,
    Case When Min(D.Rolling_Qty_Available) Over ( PARTITION BY D.upc) < 1 then 0 else 
    Min(D.Rolling_Qty_Available) Over ( PARTITION BY D.upc) END as Qty_Available_1,
    Case When Max(D.Look_up_Ref) Over ( PARTITION BY D.upc) = 0 then '-1000' else 
    Max(D.Look_up_Ref) Over ( PARTITION BY D.upc) END as Look_up_Ref_1

From
    (
    Select 
    A.Upc,
    A.name,
    A.Week_end_Date,
    A.Rolling_Qty_Available,
    CASE WHEN 
    C.Max_Row = A.Row_num and A.[Rolling_Qty_Available] >1 THEN 1 
    ELSE
    CASE WHEN
    Sum(A.Calc_Row_Thing) OVER (Partition by A.UPC Order by A.Row_Num DESC
    ROWS BETWEEN UNBOUNDED PRECEDING 
    AND   Current ROW
    ) = (C.Max_Row - A.Row_num + 1)
    THEN
    C.Max_Row - A.Row_num + 1
    ELSE 0 END 
    END as Look_up_Ref

    FROM    (
                        Select
                        G.Upc,
                        G.Name,
                        G.Week_End_Date,
                        G.Row_num,
                        G.Calc_Row_Thing,
                        G.Rolling_Qty_Available 
                        --CASE When (G.Rolling_Qty_Available - 
                        --isnull(H.Qty_Available_1,0)) > 0 then 1 else - 0 END as 
                        --Calc_Row_Thing,


                        From [dbo].[ATS_item_detail_USA_vw] as G
                        --Left Join [dbo].[tmp_ats_usa_qty_1] as H on G.upc = H.upc

            ) AS A --Need to subtract QTY 1 out of here and below

join ( 

        SELECT 
        B.upc,
        Max(Row_num) AS Max_Row

        FROM [dbo].[ATS_item_detail_USA_vw] AS B

        GROUP BY B.upc

        ) as C on A.upc = C.upc

    ) as D

GROUP BY 
D.Upc,
D.name,
D.Rolling_Qty_Available,
D.Look_up_Ref
HAVING Max(D.Look_up_Ref) > 1
) as E 

Left join 
        (
        SELECT 
        A.Upc,
        A.name,
        A.Week_end_Date,
        A.Rolling_Qty_Available,
        CASE WHEN 
        C.Max_Row = A.Row_num and A.[Rolling_Qty_Available] >1 THEN 1 
        ELSE
        CASE WHEN
        Sum(A.Calc_Row_Thing) OVER (Partition by A.UPC Order by A.Row_Num DESC
        ROWS BETWEEN UNBOUNDED PRECEDING 
        AND   Current ROW
        ) = (C.Max_Row - A.Row_num + 1)
        THEN
        C.Max_Row - A.Row_num + 1
        ELSE 0 END 
        END as Look_up_Ref

        From (

                            Select
                        G.Upc,
                        G.Name,
                        G.Week_End_Date,
                        G.Row_num,
                        G.Calc_Row_Thing,
                        G.Rolling_Qty_Available 
                        --CASE When (G.Rolling_Qty_Available - 
                        --isnull(H.Qty_Available_1,0)) > 0 then 1 else - 0 END as 
                        --Calc_Row_Thing,


                        From [dbo].[ATS_item_detail_USA_vw] as G
                        --Left Join [dbo].[tmp_ats_usa_qty_1] as H on G.upc = H.upc

            ) as A --subtract qty_1 out the start qty 2 calc

        join ( 
                    SELECT 
                    B.upc,
                    Max(Row_num) as Max_Row

                    FROM [dbo].[ATS_item_detail_USA_vw] as B

                        GROUP BY B.upc
                ) AS C ON A.upc = C.upc

            ) AS F ON E.upc = F.upc and E.Look_up_Ref_1 = F.Look_up_Ref
0 голосов
/ 11 июля 2019

Это должно вернуть ожидаемый результат:

SELECT Item_Number, Min(week_end_date), Sum("+/-")
FROM
 (
   SELECT *
      -- put a positive value plus all following negative values in the same group
      -- using a Cumulative Sum over 0/1
     ,Sum(CASE WHEN "+/-" > 0 THEN 1 ELSE 0 end) 
      Over (PARTITION BY Item_Number
            ORDER BY week_end_date
            ROWS UNBOUNDED PRECEDING) AS grp
   FROM my_table
 ) AS dt
WHERE grp <= 3 -- only the 1st 3 groups
GROUP BY Item_Number, grp
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...