即使没有数据,也可以从表中显示数据!!神谕

时间:2012-05-13 10:32:09

标签: sql oracle11g

我有一个查询,显示根据日期收到的邮件数。 对于Eg:

1 | 1-May-2012 
3 | 3-May-2012 
4 | 6-May-2012 
7 | 7-May-2012 
9 | 9-May-2012 
5 | 10-May-2012 
1 | 12-May-2012

正如您在某些日期所看到的,没有收到任何消息。我想要的是它应该显示所有日期,如果没有收到消息,它应该显示0像这样

1 | 1-May-2012
0 | 2-May-2012
3 | 3-May-2012
0 | 4-May-2012
0 | 5-May-2012
4 | 6-May-2012
7 | 7-May-2012
0 | 8-May-2012
9 | 9-May-2012
5 | 10-May-2012
0 | 11-May-2012
1 | 12-May-2012

如果表格中没有行,我该如何实现?

3 个答案:

答案 0 :(得分:1)

首先,听起来你的应用程序会受益于日历表。日历表是日期列表和日期信息。

其次,您可以在不使用临时表的情况下执行此操作。这是方法:

with constants as (select min(thedate>) as firstdate from <table>)
     dates as (select( <firstdate> + rownum - 1) as thedate
               from (select rownum
                     from <table> cross join constants
                     where rownum < sysdate - <firstdate> + 1
                    ) seq
              )
select dates.thedate, count(t.date)
from dates left outer join
     <table> t
     on t.date = dates.thedate
group by dates.thedate

这是个主意。别名常量会在表中记录最早的日期。别名日期然后创建一系列日期。内部子查询使用rownum计算整数序列,然后将这些整数添加到第一个日期。请注意,这假设您每个日期平均至少有一笔交易。如果没有,你可以使用更大的桌子。

最后一部分是用于返回日期信息的联接。注意使用count(t.date)而不是count(*)。这会计算表中记录的数量,对于没有数据的日期,它应为0。

答案 1 :(得分:0)

您可以通过左外连接 IF 实现此目的,您有另一个要加入的表,其中包含所有可能的日期。

一个选项可能是在临时表中生成日期并将其连接到您的查询。

这样的事情可能会成功。

CREATE TABLE #TempA (Col1 DateTime)
DECLARE @start DATETIME = convert(datetime, convert(nvarchar(10), getdate(), 121))
SELECT @start

DECLARE @counter INT = 0

WHILE @counter < 50
BEGIN
    INSERT INTO #TempA (Col1) VALUES (@start)
    SET @start = DATEADD(DAY, 1, @start)
    SET @counter = @counter+1
END

这将创建一个TempTable来保存日期......我刚刚从今天开始生成了50个。

SELECT 
    a.Col1,
    COUNT(b.MessageID)
FROM
    TempA a
    LEFT OUTER JOIN YOUR_MESSAGE_TABLE b
        ON a.Col1 = b.DateColumn
GROUP BY
    a.Col1

然后你可以将你的消息计数加入到那里。

答案 2 :(得分:0)

您不需要单独的表,您可以在查询中创建所需的内容。这适用于五月:

WITH month_may AS (
    select to_date('2012-05-01', 'yyyy-mm-dd') + level - 1 AS the_date
    from dual
    connect by level < 31
)
SELECT *
  FROM month_may mm
  LEFT JOIN mytable t ON t.some_date = mm.the_date

日期范围取决于您希望如何做到这一点以及您的范围。