合并语句来处理多个值和 NULLS?

Coalesce statement to handle multiple values and NULLS?

我正在尝试弄清楚如何创建一个 SQL 查询来检查 (:FROM_DATE) 和 (:TO_DATE) 参数以及是否要将 NULL过去一个月的日期为这两个值,如果不是 NULL 则接受在参数中输入的任何值。

例如:

有人提示我使用合并语句来处理多个值和 NULLS(即 AND ( (coalesce(null, :P_ORG) is null) or (ORG.ORGANIZATION_ID in :P_ORG)))???

如有任何帮助,我们将不胜感激。

类似于:

SELECT *
FROM   your_table
WHERE  your_date_column BETWEEN TO_DATE( :from_date, 'DD-MON-YYYY' )
                        AND     TO_DATE( :to_date, 'DD-MON-YYYY' )
OR     (   ( :from_date IS NULL OR :to_date IS NULL )
       AND your_date_column BETWEEN ADD_MONTHS( TRUNC( SYSDATE, 'MM' ), -1 )
                            AND     TRUNC( SYSDATE, 'MM' ) - 1
       );

如果 :from_date:to_date 之一(或两者)为 NULL,则日期将与上个月进行比较。

如果您的 table 日期的时间部分并不总是设置为午夜,那么您将需要使用:

SELECT *
FROM   your_table
WHERE  your_date_column BETWEEN TO_DATE( :from_date, 'DD-MON-YYYY' )
                        AND     TO_DATE( :to_date, 'DD-MON-YYYY' )
OR     (   ( :from_date IS NULL OR :to_date IS NULL )
       AND your_date_column >= ADD_MONTHS( TRUNC( SYSDATE, 'MM' ), -1 )
       AND your_date_column <  TRUNC( SYSDATE, 'MM' )
       );

概念验证:考虑以下查询,其中我们有日期和值,我们想要对介于 :from_date:to_date 之间的日期的值求和。如果它们中的任何一个是 null,查询将使用前一个月的第一天作为 from_date,并使用前一个月的最后一天作为 to_date。请注意,如果一个日期被赋予实际值而另一个被保留 null,这将导致 问题 - 您没有解释您希望如何处理。但那是另一回事了。

我使用 SQL 开发人员,但我不知道如何在其中传递日期;我展示了传入字符串,并将它们转换为日期。

with
     test_data ( dt, val ) as (
       select date '2017-05-29', 200 from dual union all
       select date '2017-06-13', 150 from dual union all
       select date '2017-06-18', 500 from dual
     )
select sum(val) as sum_val
from   test_data
where  dt between coalesce(to_date(:from_date, 'yyyy-mm-dd'), 
                                                   add_months(trunc(sysdate, 'mm'), -1))
              and coalesce(to_date(:to_date  , 'yyyy-mm-dd'), trunc(sysdate, 'mm') - 1)
;

是的,您可以使用 COALESCE(或 Oracle 的 NVL)。当参数为空时,将其替换为默认日期。

select *
from mytable
where mydate >= coalesce(:from_date, trunc(sysdate - interval '1' month), 'month')
  and mydate <= coalesce(:to_date, last_day(sysdate - interval '1' month));