我在做一个小旅社预订项目。我试着在网格上创建一个日历列表,该列表显示一个月的所有日期,旁边是招待所的事务详细信息(预订详细信息或预订详细信息)。
这是我的样本数据:
事务表
SALE_PK SALESPARTICULAR SALES_DATEFROM SALES_DATETO
------------------------------------------------------------
1 Room 1-Reserved 5/17/2019 5/18/2019
2 Room 2-Reserved 5/18/2019 5/20/2019
3 Room 3-Reserved 5/22/2019 5/23/2019下面是我想要的输出:
选择程序
GET_DATE SALES_DSCRPTION
--------------------------
5/1/2019 Null
5/2/2019 Null
5/3/2019 Null
5/4/2019 Null
5/5/2019 Null
5/6/2019 Null
5/7/2019 Null
5/8/2019 Null
5/9/2019 Null
5/10/2019 Null
5/11/2019 Null
5/12/2019 Null
5/13/2019 Null
5/14/2019 Null
5/15/2019 Null
5/16/2019 Null
5/17/2019 Room 1-Reserved 5/17/2019-5/18/2019
5/18/2019 Room 1-Reserved 5/17/2019-5/18/2019
5/18/2019 Room 2-Reserved 5/18/2019-5/20/2019
5/19/2019 Room 2-Reserved 5/18/2019-5/20/2019
5/20/2019 Room 2-Reserved 5/18/2019-5/20/2019
5/21/2019 Null
5/22/2019 Room 3-Reserved 5/22/2019-5/23/2019
5/23/2019 Room 3-Reserved 5/22/2019-5/23/2019
5/24/2019 Null
5/25/2019 Null
5/26/2019 Null
5/27/2019 Null
5/28/2019 Null
5/29/2019 Null
5/30/2019 Null
5/31/2019 Null我的选择过程只能在一个日期上得到一个数据。
下面是我的过程的实际输出
GET_DATE SALES_DSCRPTION
---------------------------
5/14/2019 Null
5/15/2019 Null
5/16/2019 Null
5/17/2019 Room 1-Reserved 5/17/2019-5/18/2019
5/18/2019 Room 1-Reserved 5/17/2019-5/18/2019
5/19/2019 Room 2-Reserved 5/18/2019-5/20/2019
5/20/2019 Room 2-Reserved 5/18/2019-5/20/2019
5/21/2019 Null
5/22/2019 Room 3-Reserved 5/22/2019-5/23/2019
5/23/2019 Room 3-Reserved 5/22/2019-5/23/2019
5/24/2019 Null
5/25/2019 Null
...我希望在一个日期中显示多个事务。
我创建了一个过程,它将显示每月的所有日期。
CREATE PROCEDURE DAYS_IN_MONTH(
Y INTEGER,
M INTEGER)
RETURNS(
D DATE)
AS
begin
d = cast(y || '-' || m || '-01' as date);
while (extract(month from d) = m) do
begin
suspend;
d = d + 1;
end
end;并将此过程调用到我的主选择过程中。
这是我正在进行的选择过程。
CREATE PROCEDURE SALES_LISTCALENDAR(
Y INTEGER,
M INTEGER)
RETURNS(
MONTHDATE DATE,
DAYINWORDS VARCHAR(20) CHARACTER SET ISO8859_1 COLLATE ISO8859_1,
SALES_DSCRPTION VARCHAR(200) CHARACTER SET ISO8859_1 COLLATE ISO8859_1)
AS
DECLARE VARIABLE COMPLETE_DATE DATE;
BEGIN
FOR
SELECT
DAYS_IN_MONTH.D,
1 + DAYS_IN_MONTH.D,
CASE extract (WEEKDAY from DAYS_IN_MONTH.D)
WHEN '0' THEN 'Sunday'
WHEN '1' THEN 'Monday'
WHEN '2' THEN 'Tuesday'
WHEN '3' THEN 'Wednesday'
WHEN '4' THEN 'Thursday'
WHEN '5' THEN 'Friday'
WHEN '6' THEN 'Saturday'
ELSE '' END,
A.SALESPARTICULAR
FROM DAYS_IN_MONTH (:Y, :M)
LEFT JOIN
(SELECT A.SALE_PARTICULARS AS SALESPARTICULAR
FROM SALES A WHERE :COMPLETE_DATE >= A.SALES_DATEFROM AND :COMPLETE_DATE <= A.SALES_DATETO
GROUP BY A.SALE_PARTICULARS ) A ON DAYS_IN_MONTH.D = :COMPLETE_DATE
INTO
:MONTHDATE,
:COMPLETE_DATE,
:DAYINWORDS,
:SALES_DSCRPTION
DO
BEGIN
SUSPEND;
END
END;实际结果
GET_DATE SALES_DSCRPTION
...
5/14/2019 Null
5/15/2019 Null
5/16/2019 Null
5/17/2019 Room 1-Reserved 5/17/2019-5/18/2019
5/18/2019 Room 1-Reserved 5/17/2019-5/18/2019
5/19/2019 Room 2-Reserved 5/18/2019-5/20/2019
5/20/2019 Room 2-Reserved 5/18/2019-5/20/2019
5/21/2019 Null
5/22/2019 Room 3-Reserved 5/22/2019-5/23/2019
5/23/2019 Room 3-Reserved 5/22/2019-5/23/2019
5/24/2019 Null
5/25/2019 Null
...我的选择过程只能在一个日期上得到一个数据。
以下是所需的输出
GET_DATE SALES_DSCRPTION
...
5/14/2019 Null
5/15/2019 Null
5/16/2019 Null
5/17/2019 Room 1-Reserved 5/17/2019-5/18/2019
5/18/2019 Room 1-Reserved 5/17/2019-5/18/2019
5/18/2019 Room 2-Reserved 5/18/2019-5/20/2019
5/19/2019 Room 2-Reserved 5/18/2019-5/20/2019
5/20/2019 Room 2-Reserved 5/18/2019-5/20/2019
5/21/2019 Null
5/22/2019 Room 3-Reserved 5/22/2019-5/23/2019
5/23/2019 Room 3-Reserved 5/22/2019-5/23/2019
5/24/2019 Null
5/25/2019 Null
...发布于 2019-05-18 06:13:16
您在select中使用:COMPLETE_DATE非常可疑,即使在select开始时它是NULL。我甚至没有意识到Firebird会在执行过程中填充和应用变量,就像它是一个别名一样。另外,这个子选择本身看起来很奇怪,我不知道你想用它做什么。
从一个小测试(5月1日添加一个带有SALES_DATEFROM的记录)来看,这似乎是由于评估顺序:在该子选择的WHERE-clause中,:COMPLETE_DATE变量仍然具有上一行的值(这可能就是为什么您将其定义为1 + DAYS_IN_MONTH.D)。因为五月一日是第一行,所以:COMPLETE_DATE在那时仍然是NULL。但是,在5月18日,您有两个记录(对于第1和第2房间),但是当计算了第2房间的记录时,联接条件就不再适用了,因为在输出第1房间的记录时已经更新了:COMPLETE_DATE值。
长话短说:不会在同一个查询中使用查询的输出变量。考虑到评估顺序的副作用,它们的行为应该被认为是不明确的。
顶替
FROM DAYS_IN_MONTH (:Y, :M)
LEFT JOIN
(SELECT A.SALE_PARTICULARS AS SALESPARTICULAR
FROM SALES A WHERE :COMPLETE_DATE >= A.SALES_DATEFROM AND :COMPLETE_DATE <= A.SALES_DATETO
GROUP BY A.SALE_PARTICULARS ) A ON DAYS_IN_MONTH.D = :COMPLETE_DATE使用
FROM DAYS_IN_MONTH (:Y, :M)
LEFT JOIN
SALES A on DAYS_IN_MONTH.D BETWEEN A.SALES_DATEFROM AND A.SALES_DATETO在我看来也更容易理解。
发布于 2019-05-18 10:33:43
对于这样一个简单的任务,不需要使用复杂的代码:它只会让您感到困惑。
似乎您只需要一个简单的基于循环的存储过程,它在时间跨度(最左边的列)中生成所有日期,然后您只需使用订票表执行SP的LEFT JOIN。有点像
Select D, SALESPARTICULAR || ' ' || SALES_DATEFROM || ' - ' || SALES_DATETO
From DAYS_IN_MONTH(...)
LEFT JOIN Transactions
ON D BETWEEN SALES_DATEFROM AND SALES_DATETOhttps://stackoverflow.com/questions/56187864
复制相似问题