Sql-Server

如何編寫選擇語句,根據partid 從最後一個日期到目前日期獲取數據並填補空白?

  • March 30, 2022

select statment我在 sql server 2012 上工作,我遇到了從上個月到本月無法獲取 Partid 的問題march (3)

基於last date存在每partid

並在同一時間,如果有的話,gaps between dates然後根據最後日期填寫

因此,如果

我找到了最後日期為 2022-01-08 的 partid,然後我將添加08-02-202208-03-2022作為 partid6070

如果partid在一個月7和下個月有日期,並且在第 8個月10沒有日期part id

和 9 然後它必鬚gaps根據上個月顯示這個,因為 partid 1234 有 gap 。

這兩種情況都必須適用於所有基於partid.

Createddate下面在甲酸鹽上使用yyyy-mm-dd

create table Parts
(
   
PartId int,
CreatedDate date
)
insert into Parts(PartId,CreatedDate)
values
(1234,'2021-07-03'),
(1234,'2021-10-05'),
(1234,'2021-11-05'),
(5981,'2021-11-15'),
(5981,'2021-12-03'),
(6070,'2021-12-12'),
(6070,'2022-01-08')

我需要按預期結果select statment顯示parts

green rows只是為了更清楚,這些零件必須在舊零件添加之前存在。

預期結果

與上次日期的日期的文件間隙

我嘗試什麼

更新後的文章

下面的程式碼給了我預期結果的一部分

因為它給了我剩餘日期之間的空白以獲取目前月份的日期

那麼該怎麼做呢?

;with cte as (
  select partid, createddate,
         dateadd(month, -1,
                 coalesce(lead(createddate) over (partition by partid order by createddate),
                          max(createddate) over ()
                         )
                ) as end_month
  from Parts
  union all
  select partid, dateadd(month, 1, createddate), end_month
  from cte
  where createddate <end_month
 )
select *
from cte
order by partid, createddate

看起來您遇到的問題是缺少數據。當給定日期沒有結果集時,就沒有分組依據的日期。

要解決此問題,您可以創建一個跨越數據范圍的間隔 CTE,然後使用 LEFT OUTER 連接將其連接到您的數據。這將您範圍內的所有間隔提供給查詢

首先讓我們模擬一些數據進行測試:

DECLARE @mockTable TABLE (InvoiceID INT IDENTITY, invoiceDate DATE, invoiceAmount MONEY)
SET NOCOUNT ON
WHILE (SELECT COUNT(*) FROM @mockTable) < 300
BEGIN
INSERT INTO @mockTable (invoiceDate, invoiceAmount) VALUES (DATEADD(DAY, -ROUND(((89 - 0 -1) * RAND() + 1), 0),CAST(GETDATE() AS DATE)), ((100 - 1 -1) * RAND() + 1) - 1)
END

@mockTable 現在包含 300 行隨機生成的數據,日期為今年。使用它,我們可以匯總每天的總發票,如果有的話:

;WITH dateRange AS (
SELECT CAST(CAST(DATEPART(YEAR,CAST(GETDATE() AS DATE)) AS VARCHAR)+'-1-1' AS DATE) AS Interval
UNION ALL
SELECT DATEADD(DAY,1,Interval)
 FROM dateRange
WHERE Interval <= CAST(GETDATE() AS DATE)
)

SELECT dr.interval, SUM(invoiceAmount) AS totalInvoiceAmount, COUNT(invoiceID) AS totalInvoices
 FROM dateRange dr
   LEFT OUTER JOIN @mockTable mt
     ON dr.Interval = mt.invoiceDate
GROUP BY dr.Interval
OPTION (MAXRECURSION 0)

名為 dateRange 的 CTE 包含從年初到明天的每個日期。將它連接到您的數據(或 mockTable 數據)現在會為該範圍內的每一天生成一個結果,當該日期沒有發票時,totalInvoiceAmount 為 NULL,totalInvoices 計數為 0。

展示螢幕抓取

您可以對數據應用類似的技術。hth

引用自:https://dba.stackexchange.com/questions/308773