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

后端 未结 3 1733
悲&欢浪女
悲&欢浪女 2021-01-25 05:34

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 |         


        
相关标签:
3条回答
  • 2021-01-25 05:37

    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.

    0 讨论(0)
  • 2021-01-25 05:51

    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.

    0 讨论(0)
  • 2021-01-25 06:03

    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.

    0 讨论(0)
提交回复
热议问题