Show data from table even if there is no data!! Oracle

拥有回忆 提交于 2019-12-31 05:09:53

问题


I have a query which shows count of messages received based on dates. For 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

As you can see on some dates there are no messages received. What I want is it should show all the dates and if there are no messages received it should show 0 like this

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

How can I achieve this when there are no rows in the table?


回答1:


You don't need a separate table for this, you can create what you need in the query. This works for May:

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

The date range will depend on how exactly you want to do this and what your range is.




回答2:


First, it sounds like your application would benefit from a calendar table. A calendar table is a list of dates and information about the dates.

Second, you can do this without using temporary tables. Here is the approach:

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

Here is the idea. The alias constants records the earliest date in your table. The alias dates then creates a sequence of dates. The inner subquery calculates a sequence of integers, using rownum, and then adds these to the first date. Note this assumes that you have on average at least one transaction per date. If not, you can use a bigger table.

The final part is the join that is used to bring back information about the dates. Note the use of count(t.date) instead of count(*). This counts the number of records in your table, which should be 0 for dates with no data.




回答3:


You could achieve this with a left outer join IF you had another table to join to that contains all possible dates.

One option might be to generate the dates in a temp table and join that to your query.

Something like this might do the trick.

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

That will create a TempTable to hold the dates... I've just generated 50 of them starting from today.

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

Then you can left join your message counts to that.



来源:https://stackoverflow.com/questions/10571025/show-data-from-table-even-if-there-is-no-data-oracle

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!