方案

时间:2015-10-27 09:29:58

标签: oracle11g oracle-sqldeveloper

我有以下查询,提供如下数据

SELECT NO, PRODUCT_CODE, DATE, QTY
FROM DAILY_QAUNTITY
WHERE CODE = '10' ;



NO      CODE      DATE        QTY 

6750    105581   5-Feb-14    57 

6750    105581  12-Feb-14    46

6750    105581  17-Feb-14    41 
6751    11028   18-feb-14    40
6751    11028   19-feb-14    38
6751    11028   20-feb-14    35
6751    11028   21-feb-14    30

但我需要输出

NO       CODE    DATE      QTY

6750    105581  5-Feb-14    57 

6750    105581  6-Feb-14    57 

6750    105581  7-Feb-14    57 

6750    105581  8-Feb-14    57 

6750    105581  9-Feb-14    57 

6750    105581  10-Feb-14   57 

6750    105581  11-Feb-14   57 

6750    105581  12-Feb-14   46 

6750    105581  13-Feb-14   46 

6750    105581  14-Feb-14   46 

6750    105581  15-Feb-14   46 

6750    105581  16-Feb-14   46 

6750    105581  17-Feb-14    41 
6751    11028   18-feb-14    40
6751    11028   19-feb-14    38
6751    11028   20-feb-14    35
6751    11028   21-feb-14    30

我们可以看到,在第5个月之后的第一个输出中,它跃升至12日元。您可以在第二个输出中观察日期是从5到11的序列,具有相同的数据。如何编写sql查询来带来这个输出。

5 个答案:

答案 0 :(得分:2)

@Venkat,因为你的问题主要在于日期生成,所以Query主要关注它。这是相同的SQL Server版本。它使用递归CTE。

;WITH Dates as
 (
    SELECT
        [Date] = CAST('2014-02-05' AS DATE) 
    UNION ALL 

    SELECT      
        DATEADD(DAY , 1, [Date]) 
    FROM Dates
    WHERE DATEADD (DAY, 1, [Date]) <= '2014-02-17'
 )

SELECT 
    [NO] = 6750 
    ,[CODE] = 105581    
    ,[Date] = REPLACE(CONVERT(NVARCHAR, [Date], 106),' ','-')
    ,[QTY] = CASE WHEN [Date] >= '2014-02-05' AND [Date] <='2014-02-11' THEN 57
                  WHEN [Date] >= '2014-02-12' AND [Date] <='2014-02-16' THEN 46
                  WHEN [Date] >= '2014-02-17' THEN 41
            END
 FROM Dates
 OPTION (MAXRECURSION 0);

enter image description here

您也可以通过其他方式执行日期日历生成。

以下是一些不错的例子

a)How to create a Calender table for 100 years in Sql

b)How to generate a range of dates in SQL Server

在Oracle中,您可以按照以下方法

WITH DatesCTE AS
(
        SELECT
                (to_date('05-02-2014','DD-MM-YYYY') - level + 1) AS day
        FROM dual
        CONNECT BY LEVEL <= (to_date('05-02-2014','DD-MM-YYYY') - to_date('17-02-2014','DD-MM-YYYY') + 1)
)

SELECT
    [NO] = 6750 
    ,[CODE] = 105581
    ,[Date]  = day
FROM DatesCTE   

有关在Oracle中生成日期范围的更多方法,请参阅this SO讨论。

更新(没有WITH子句的日期生成)

SELECT
    (to_date('05-02-2014','DD-MM-YYYY') - level + 1) AS day
FROM dual
CONNECT BY LEVEL <= (to_date('05-02-2014','DD-MM-YYYY') - to_date('17-02-2014','DD-MM-YYYY') + 1)

希望这有帮助。

答案 1 :(得分:0)

尝试使用ORDER BY

SELECT NO, PRODUCT_CODE, DATE, QTY
FROM DAILY_QAUNTITY
WHERE CODE = '10' 
ORDER BY DATE;

答案 2 :(得分:0)

SELECT    
      (
        SELECT "no" 
        FROM 
            (SELECT 
                "no"
                , code
                , "date" currdate
                , qty
                , lead("date") over (order by "date") leaddate 
              FROM daily_quantity) dq 
       WHERE date1 BETWEEN dq.currdate AND NVL(dq.leaddate-1,dq.currdate)
      ) "no",  
      (SELECT code 
      FROM 
        (SELECT 
                "no"
                , code
                , "date" currdate
                , qty
                , lead("date") over (order by "date") leaddate  
         FROM daily_quantity) dq
       WHERE date1 BETWEEN dq.currdate AND NVL(dq.leaddate-1,dq.currdate)
      ) code,     
      date1,    
      (SELECT qty 
      FROM 
        (SELECT "no"
                , code
                , "date" currdate
                , qty
                , lead("date") over (order by "date") leaddate 
          FROM daily_quantity) dq
       WHERE date1 BETWEEN dq.currdate AND NVL(dq.leaddate-1,dq.currdate)
      ) qty   
    FROM   
      ( 
            SELECT 
            (
                (SELECT MIN("date") 
                FROM daily_quantity) + level -1
            ) date1
            FROM dual   
            CONNECT BY level <= 
            (SELECT MAX("date") FROM daily_quantity) - (SELECT MIN("date") 
            FROM daily_quantity) + 1
      );

答案 3 :(得分:0)

SELECT  inn2.date1,    
        LAST_VALUE(inn2.numbers IGNORE NULLS) OVER (ORDER BY date1 ) "no",    
        LAST_VALUE(inn2.code IGNORE NULLS) OVER (ORDER BY date1 ) code,    
        LAST_VALUE(inn2.qty IGNORE NULLS) OVER (ORDER BY date1 ) qty    
FROM    
   (    SELECT inn1.date1,    
            MAX(DQ."no") numbers,    
            MAX(DQ.code) code,    
            MAX(DQ.qty) qty    
        FROM (  SELECT ( (SELECT MIN("date") FROM daily_quantity) + level -1 ) date1     
                FROM dual    
                CONNECT BY level <= (SELECT MAX("date") FROM daily_quantity) - (SELECT MIN("date") FROM daily_quantity) + 1    
    ) inn1, daily_quantity DQ    
WHERE inn1.date1 = DQ."date"(+)    
GROUP BY DQ."no",
        DQ.code,
        DQ.qty,
        inn1.date1
) inn2 ;

答案 4 :(得分:-2)

希望这对你有用...... 虽然可以进一步优化

with dq as
( 
select "no", code, "date" currdate, qty, lead("date") over (order by "date") leaddate 
from daily_quantity
)
select  
(select "no" from dq where date1 between dq.currdate and nvl(dq.leaddate-1,dq.currdate)) "no",
(select code from dq where date1 between dq.currdate and nvl(dq.leaddate-1,dq.currdate)) code,
 date1,
(select qty from dq where date1 between dq.currdate and nvl(dq.leaddate-1,dq.currdate)) qty
from 
(select ((select min("date") from daily_quantity) + level -1) date1
from dual
connect by level <= (select max("date") from daily_quantity) - (select min("date") from daily_quantity) + 1);