首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用左联接显示日历列表选择过程,并在单个日期中显示多个数据

使用左联接显示日历列表选择过程,并在单个日期中显示多个数据
EN

Stack Overflow用户
提问于 2019-05-17 13:51:48
回答 2查看 60关注 0票数 1

我在做一个小旅社预订项目。我试着在网格上创建一个日历列表,该列表显示一个月的所有日期,旁边是招待所的事务详细信息(预订详细信息或预订详细信息)。

这是我的样本数据:

事务

代码语言:javascript
运行
复制
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

下面是我想要的输出:

选择程序

代码语言:javascript
运行
复制
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

我的选择过程只能在一个日期上得到一个数据。

下面是我的过程的实际输出

代码语言:javascript
运行
复制
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
...

我希望在一个日期中显示多个事务。

我创建了一个过程,它将显示每月的所有日期。

代码语言:javascript
运行
复制
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;

并将此过程调用到我的主选择过程中。

这是我正在进行的选择过程。

代码语言:javascript
运行
复制
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;

实际结果

代码语言:javascript
运行
复制
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
...

我的选择过程只能在一个日期上得到一个数据。

以下是所需的输出

代码语言:javascript
运行
复制
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
...
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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值。

长话短说:不会在同一个查询中使用查询的输出变量。考虑到评估顺序的副作用,它们的行为应该被认为是不明确的。

顶替

代码语言:javascript
运行
复制
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

使用

代码语言:javascript
运行
复制
FROM DAYS_IN_MONTH (:Y, :M)
LEFT JOIN
  SALES A on DAYS_IN_MONTH.D BETWEEN A.SALES_DATEFROM AND A.SALES_DATETO

在我看来也更容易理解。

票数 2
EN

Stack Overflow用户

发布于 2019-05-18 10:33:43

对于这样一个简单的任务,不需要使用复杂的代码:它只会让您感到困惑。

似乎您只需要一个简单的基于循环的存储过程,它在时间跨度(最左边的列)中生成所有日期,然后您只需使用订票表执行SP的LEFT JOIN。有点像

代码语言:javascript
运行
复制
Select D, SALESPARTICULAR || '   ' || SALES_DATEFROM || '  -  ' || SALES_DATETO 
From DAYS_IN_MONTH(...) 
    LEFT JOIN Transactions
        ON D BETWEEN SALES_DATEFROM AND SALES_DATETO
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56187864

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档