我正在设计一个报表,该报表将在未来一周返回PurchaseOrder到期。
我在下面添加的查询针对特定的PurchaseOrder
,Commodity
及其AmountDue
返回DeliveryDate
。
很显然,它仅返回表中的PO_Date。我想要的是还包括没有订单预期的日期,即那些单元格为空。
对我来说,一种可能性是在“日期”列上保留具有未来一周日期集的数据集,这将最终使结果(如果没有采购订单的情况下)为空。
在Firebird中,我不知道如何选择一个星期的日期列表,然后在联接中使用它。
SELECT
PURCHASE_ORDER_DET.COMMODITYID AS COM_ID,
PURCHASE_ORDER_DET.DELIVERYDATE + CAST ('29.12.1899' AS DATE) as DLV_DATE,
SUM(PURCHASE_ORDER_DET.REQQUANTITY) as DLV_DUE
FROM
PURCHASE_ORDER_DET
LEFT JOIN PURCHASE_ORDER_HDR on PURCHASE_ORDER_HDR.POH_ID =
PURCHASE_ORDER_DET.POH_ID
WHERE
PURCHASE_ORDER_DET.COMMODITYID = 1
AND PURCHASE_ORDER_HDR.STATUS in (0,1,2)
AND PURCHASE_ORDER_DET.DELIVERYDATE + CAST ('30.12.1899' AS TIMESTAMP) >= '3.01.2019'
AND PURCHASE_ORDER_DET.DELIVERYDATE + CAST ('30.12.1899' AS TIMESTAMP) <= '9.01.2019'
AND PURCHASE_ORDER_DET.DELETED is NULL
Group by
PURCHASE_ORDER_DET.COMMODITYID,
PURCHASE_ORDER_DET.DELIVERYDATE
数据集
COM_ID DLV_DATE DLV_DUE
1 3.01.2019 50.000000
1 5.01.2019 10.000000
期望
COM_ID DLV_DATE DLV_DUE
1 3.01.2019 50.000000
1 4.01.2019 null
1 5.01.2019 10.000000
1 6.01.2019 null
1 7.01.2019 null
1 8.01.2019 null
1 9.01.2019 null
答案 0 :(得分:0)
忽略数据类型的奇怪用法*,有几种可能的解决方案:
选项1非常不言自明。
选项2类似于:
CREATE OR ALTER PROCEDURE date_range(startdate date, enddate date)
RETURNS (dateval date)
AS
BEGIN
dateval = startdate;
while (dateval <= enddate) do
BEGIN
suspend;
dateval = dateval + 1;
END
END
然后在查询中使用它,例如:
select date_range.dateval, ...
from date_range(date'2019-01-03', date'2019-01-09') -- use date_range(?, ?) for parameters
left join ...
on date_range.dateval = ...
选项3类似于:
WITH RECURSIVE date_range AS (
SELECT date'2019-01-03' dateval -- start date, use cast(? as date) if you need a parameter
FROM rdb$database
UNION ALL
SELECT dateval + 1
FROM date_range
WHERE dateval < date'2019-01-09' -- end date use ? if you need a parameter
)
SELECT *
FROM date_range
LEFT JOIN ...
ON date_range.dateval = ...
递归公用表表达式的最大递归深度为1024,这意味着如果需要的跨度大于1024天,则不适合。
*:我建议您开始使用DATE
,而不要使用自30-12-1899以来的天数。这避免了像现在这样进行笨拙的计算。如果确实需要这些天数,则可以使用datediff(DAY FROM date'1899-12-30' TO somedatevalue)
或somedatevalue - date'1899-12-30'
将日期从日期转换为该数值。