如何使用SQL查询计算商品在库存中的时间

huangapple go评论56阅读模式
英文:

How to calculate the time an Item was in stock as SQL query

问题

以下是您的SQL查询的翻译结果,我将提取出您要计算的日期:

WITH CTE AS (
  SELECT dBooked, tAvailable, 
         ROW_NUMBER() OVER (ORDER BY dBooked) - 
         ROW_NUMBER() OVER (PARTITION BY tAvailable ORDER BY dBooked) AS group_id
  FROM (
    SELECT dBooked, tAvailable
    FROM tArtikelHistory
    WHERE kArticle = 250
    UNION ALL
    SELECT SYSDATETIME(), 0
  ) t
),
CTE2 AS (
  SELECT MIN(dBooked) AS start_date, MAX(dBooked) AS end_date, tAvailable, group_id
  FROM CTE
  GROUP BY group_id, tAvailable
)
SELECT start_date, end_date, tAvailable, 
       LAG(end_date) OVER (ORDER BY start_date) AS prev_end_date,
       CASE WHEN tAvailable = 0 THEN DATEDIFF(day, LAG(end_date) OVER (ORDER BY start_date), end_date) END AS gap_in_days
FROM CTE2

这个查询将计算您所需的日期,并返回结果。现在,您可以根据需要将gap_in_days进行汇总以获得总天数。

英文:

Ok since my first attempt was not to understand, I'll try again.

I'm trying to write a query with SQL that at the end gives me the total days that a physical item has been in stock, i.e. greater than 0.

The table has 3 fields
kArticle dBooked tAvailable

I want to calculate the times in which tAvailable > 0 has been.

my problem is that whenever a sale has taken place an entry is created and therefore there are many entries where tAvailable > 0.

I am only interested in the time from the goods receipt to the time when it was no longer available.

so i have to try to get rid of the useless data or make it clear to the query that the table has to be processed in chronological order and only the oldest values are interesting no matter how many values follow that are also greater than 0.

This table should serve as an example.
in the simplest case the data would look like this

kArticle dBooked tAvailable
250 01.01.2020 1
250 10.01.2020 0
250 20.01.2020 1
250 30.01.2020 0

what I have to do now is quite simple, I have to calculate :

when tAvailable = 0 then (dBooked) - ( pref dBooked)

and to format this into Date so the Table would / should look like this:

kArticle dBooked tAvailable DaysAvaiable
250 01.01.2020 1 0
250 10.01.2020 0 10
250 20.01.2020 1 0
250 30.01.2020 0 10

but what do i do when the table looks like this:

kArticle dBooked tAvailable
250 01.01.2020 5
250 10.01.2020 4
250 20.01.2020 3
250 30.01.2020 2
250 10.02.2020 1
250 20.02.2020 0

My idea was to use a helper field since iam only interested in the 01.01.2020 date and the date 20.02.2020

if tAvailable >0 and pref. tAvailable !>0 
then helper = 1 
Else
""*no entry*

Plus

if tAvailable <= 0 and pref tAvailable !<=0
then helper = 0
ELSE
""*no entry*

That would / should create this table

kArticle dBooked tAvailable Helper
250 01.01.2020 5 1
250 10.01.2020 4
250 20.01.2020 3
250 30.01.2020 2
250 10.02.2020 1
250 20.02.2020 0 0

i just need to dont display helper = "" to get this

kArticle dBooked tAvailable Helper
250 01.01.2020 5 1
250 20.02.2020 0 0

and now i can just do the same thing again

when Helper = 0 then (dBooked) - ( pref dBooked)

first of all i cant realy do any of that stuff above! i just tell Chat GPT what i want and he does it for me but since i have no idea what to do in SQL iam trying what i know that would be EXCEL

thats why i work with so many if

At the end i have a few problems with my aproach:

if the first row is 0, I get an error.
If the last row is not 0, I need to create one for the date the query was executed.

i need to do the math in correct order etc etc

what ever i tried before doesnt matter i just showed you to proof i tried with what i can but what i need is this:

kArticle dBooked tAvailable DAYS in Stock
250 01.01.2020 0
250 02.01.2020 5
250 10.01.2020 4
250 20.01.2020 0 20
250 30.01.2020 2
250 10.02.2020 1
250 11.02.2020 0 11
250 11.02.2020 1
250 **added sysdatetime() ** 0 ~1000

or simply the debit value.
all days in stock added together

Days in Stock
1031

What i have so far is this:

WITH CTE AS (
  SELECT dBooked, tAvailable, 
         ROW_NUMBER() OVER (ORDER BY dBooked) - 
         ROW_NUMBER() OVER (PARTITION BY tAvailable ORDER BY dBooked) AS group_id
  FROM (
    SELECT dBooked, tAvailable
    FROM tArtikelHistory
    WHERE kArticle = 250
    UNION ALL
    SELECT SYSDATETIME(), 0
  ) t
),
CTE2 AS (
  SELECT MIN(dBooked) AS start_date, MAX(dBooked) AS end_date, tAvailable, group_id
  FROM CTE
  GROUP BY group_id, tAvailable
)
SELECT start_date, end_date, tAvailable, 
       LAG(end_date) OVER (ORDER BY start_date) AS prev_end_date,
       CASE WHEN tAvailable = 0 THEN DATEDIFF(day, LAG(end_date) OVER (ORDER BY start_date), end_date) END AS gap_in_days
FROM CTE2

now i need to sum the gap_in_days

答案1

得分: 1

你需要创建一个“组”,在这些组中,股票从大于0变为0,然后比较最小日期和零日期:

可能类似以下的内容:

-- 创建一些示例数据
select kArticle, cast(dbooked as date) as dt, CAST(tAvailable AS INT) AS tAvailable
into #data
from 
(
	VALUES (250, N'2019-12-01', 1)
	,	(250, N'2019-12-10', 0)
	,	(250, N'2019-12-20', 1)
	,	(250, N'2019-12-30', 0)
	,	(250, N'2020-01-01', 5)
	,	(250, N'2020-01-10', 4)
	,	(250, N'2020-01-20', 3)
	,	(250, N'2020-01-30', 2)
	,	(250, N'2020-02-10', 1)
	,	(250, N'2020-02-20', 0)
) t (kArticle,dBooked,tAvailable)

-- 分组
SELECT	CASE WHEN tAvailable = 0 THEN DATEDIFF(DAY, LastAvailableDay, dt) END AS [DAYS IN STOCK] -- 计算差值
,	*
FROM	(
	-- 每个组中取第一个可用日期
	SELECT	MIN(dt) OVER(PARTITION BY kArticle, PrevZero ORDER BY dt) AS LastAvailableDay
	,	*
	FROM	(
		select	*
		-- 从上一个股票为0直到下一个零的分组
		,	SUM(CASE WHEN prevAvailable = 0 THEN 1 ELSE 0 END) OVER(PARTITION BY kArticle ORDER BY dt) AS prevZero
		from (
			select	*
			,	LAG(tAvailable) OVER(PARTITION BY kArticle ORDER BY dt) AS prevAvailable
			from #data d
			) x
		) x
	) x
order by dt
			
drop table #data
英文:

What you need is to create "groups" where stock goes from > 0 to 0, and then compare the MIN date with the zero date:

Something like this perhaps:

-- Create some sample data
select kArticle, cast(dbooked as date) as dt, CAST(tAvailable AS INT) AS tAvailable
into #data
from 
(
	VALUES (250, N'2019-12-01', 1)
	,	(250, N'2019-12-10', 0)
	,	(250, N'2019-12-20', 1)
	,	(250, N'2019-12-30', 0)
	,	(250, N'2020-01-01', 5)
	,	(250, N'2020-01-10', 4)
	,	(250, N'2020-01-20', 3)
	,	(250, N'2020-01-30', 2)
	,	(250, N'2020-02-10', 1)
	,	(250, N'2020-02-20', 0)
) t (kArticle,dBooked,tAvailable)

-- Group
SELECT	CASE WHEN tAvailable = 0 THEN DATEDIFF(DAY, LastAvailableDay, dt) END AS [DAYS IN STOCK] -- Calculate diff
,	*
FROM	(
	-- Take first available day per group
	SELECT	MIN(dt) OVER(PARTITION BY kArticle, PrevZero ORDER BY dt) AS LastAvailableDay
	,	*
	FROM	(
		select	*
		-- Group from previous stock 0 until the next zero
		,	SUM(CASE WHEn prevAvailable = 0 THEN 1 ELSE 0 END) OVER(PARTITION BY kArticle ORDER BY dt) AS prevZero
		from (
			select	*
			,	LAG(tAvailable) OVER(PARTITION BY kArticle ORDER BY dt) AS prevAvailable
			from #data d
			) x
		) x
	) x
order by dt
			
drop table #data

huangapple
  • 本文由 发表于 2023年2月9日 00:25:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/75388789.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定