oracle案例还是解码? - 如何处理没有recs

时间:2011-07-20 04:33:38

标签: sql oracle case decode

我如何确保在这种情况下声明如果我now rows selected我设置了我的结果= 1? 如果我没有记录或计数为0,我想要值1。我还希望默认情况下将空日期设为sysdate。

这是我到目前为止所拥有的。它适用于(sysdate-1),但当我使用(sysdate-0)=sysdate(今天的日期)进行测试时,我 没有记录。所以我希望能够处理空值。

如何更改此查询才能执行此操作?或者我会使用像DECODE这样的东西吗?

select 
     to_date(year||'/'||month||'/'||day, 'YYYY/MM/DD') as mydt,
     case when count(*) = 0 then 1 else 0 end result
from Table1 
where 
   to_date(year||'/'||month||'/'||day, 'YYYY/MM/DD') >= trunc(sysdate)-1
GROUP BY 
    to_date(year||'/'||month||'/'||day, 'YYYY/MM/DD')

这是我的表格desc。也许,我应该取消时间戳? 还有一些计数值可能有助于更改此查询。所以我正在寻找的是即将来临 如果可能,则使用值为1或0的时间戳。

SQL> desc Table1
 Name                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 YEAR                           NUMBER
 QUARTER                        NUMBER
 MONTH                          NUMBER
 DAY                            NUMBER
 HOUR                           NUMBER
 TIMESTAMP                      NUMBER
 CNT_N                              NUMBER
 ACTN_N                             NUMBER 
 ADDR_C                       VARCHAR2(255)

4 个答案:

答案 0 :(得分:0)

对于一个组,你永远不会得到零(*)。如果没有行,则不会获得任何组,如果有行,则您获得的任何组都将显示行数。

如果1月1日有3行,1月3日有3行,您将获得:

2011/01/01 3
2011/01/03 3

你不会在1月2日获得一排。你想要产生那一行吗?是否有要返回的最大行数?

答案 1 :(得分:0)

我认为你可以修改你的查询,如下所示,将sysdate指定为空值

select
       nvl(to_date(year||'/'||month||'/'||day, 'YYYY/MM/DD') ,sysdate) as mydt
from Table1  
where
       nvl(to_date(year||'/'||month||'/'||day, 'YYYY/MM/DD') ,sysdate) 
                      >= trunc(sysdate)-1 
GROUP BY      nvl(to_date(year||'/'||month||'/'||day, 'YYYY/MM/DD') ,sysdate)

但你的第二个要求并不是很了解......请用数字来澄清你想要的东西(*)

如果您想为空日期计数分配1,那么您可以在选择陈述中添加以下行

case 
when nvl(to_date(year||'/'||month||'/'||day, 'YYYY/MM/DD') ,sysdate) = sysdate then
     1
else
count(*)-- or 0 ???!!!!!

答案 2 :(得分:0)

看起来您需要生成日期,然后查看记录如何匹配每个日期。假设您将来没有任何数据,您可以执行以下操作:

select trunc(sysdate) + level - (:range + 1) as dt
from dual
connect by level <= (:range + 1);

其中:range设置为1给出两个日期:

DT
---------
19-JUL-11
20-JUL-11

然后,您可以将外部联接添加到该日期列表中:

with tmp_dt as (
    select trunc(sysdate) + level - (:range + 1) as dt
    from dual
    connect by level <= (:range + 1)
)
select td.dt as mydt,
    case when count(t.year) = 0 then 1 else 0 end as result
from tmp_dt td
left join table1 t on t.year = extract(year from td.dt)
    and t.month = extract(month from td.dt)
    and t.day = extract(day from td.dt)
group by td.dt
order by td.dt;

如果我在19-Jul-11的表格中只有任何数据,我会得到:

MYDT          RESULT
--------- ----------
19-JUL-11          0
20-JUL-11          1

如果您将来有数据,则无法显示; range是过去多少天。如果您知道有七天的限制,您可以使用connect by level <= (:range + 1) + 7或拥有第二个变量,但这取决于您想要看到的内容。

我已经稍微交换了连接,以避免对表中的每一行进行日期转换,而是提取生成日期的相关部分。我希望您有理由将日期组件存储在单独的字段中,而不是date


如果您只是寻找今天的数据,只需更改日期生成器:

with tmp_dt as (select trunc(sysdate) as dt from dual)
select td.dt as mydt,
     case when count(t.year) = 0 then 1 else 0 end result
from tmp_dt td
left join table1 t on t.year = extract(year from td.dt)
    and t.month = extract(month from td.dt)
    and t.day = extract(day from td.dt)
group by td.dt;

如果你总是想要昨天,那就是select trunc(sysdate) - 1 as dt from dual等等。

答案 3 :(得分:0)

可以将您的整个查询封装在NVL函数中 像这样


SELECT NVL(TO_CHAR((select to_date(year || '/' || month || '/' || day,
                                  'YYYY/MM/DD') as mydt
                     from Table1
                    where to_date(year || '/' || month || '/' || day,
                                  'YYYY/MM/DD') >= trunc(sysdate) - 1
                    GROUP BY to_date(year || '/' || month || '/' || day,
                                     'YYYY/MM/DD')),
                   'DD/MM/YYYY HH:MI:SS AM'),
           '1')
  FROM DUAL

我已从查询中删除了case语句 相反,此查询将执行的操作是,如果您的查询确实返回任何值,它将不受干扰地执行此操作。但是,如果查询返回NOTHING,则NVL函数将接管并返回1 我使用TO_CHAR函数来维护NVL函数中两个参数的数据类型。返回的日期和NVL的值都是基于字符的

希望有所帮助