我有以下查询,提供如下数据
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查询来带来这个输出。
答案 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);
您也可以通过其他方式执行日期日历生成。
以下是一些不错的例子
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);