1

我有一个查询,显示基于日期收到的消息数。例如:

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

当表中没有行时,如何实现这一点?

4

3 回答 3

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。

于 2012-05-13T13:28:11.447 回答
0

如果您有另一个要加入的表包含所有可能的日期,则可以使用左外连接来实现这一点。

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

像这样的东西可能会奏效。

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

然后你可以离开加入你的消息计数。

于 2012-05-13T10:40:09.307 回答
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

日期范围将取决于您希望如何执行此操作以及您的范围是什么。

于 2012-05-13T20:09:42.073 回答