我了解基本知识,但是我是DBMS的新手,正在学习课程。
这是分配问题:
使用下表填写查询以显示最近40个月的销售量:
SALEID SID SLDATE 1001 1 01-JAN-14 1002 5 02-JAN-14 1003 4 01-FEB-14 1004 1 01-MAR-14 1005 2 01-FEB-14 1006 1 01-JUN-15
我的查询是:
select count(sldate) as sale_count
from sale
where sldate >= add_months(sysdate, -40)
期望得到的输出是:
SALE_COUNT
0
但是我收到一条错误消息:
错误:您的查询输出符合预期结果,但是存在逻辑错误。
我不确定我在哪里弄错了逻辑。
答案 0 :(得分:1)
“过去40个月”含糊不清。
“从日期x的平均值开始持续n个月做什么”的解释有几种,而oracle的add_months对此没有垄断(实际上大多数人会说它不能按预期工作,只要等到30.06,问别人“一个月前的日期是什么” :))
想象一下今天是4月20日。
“上个月”是否包括3月15日,20日,21日或25日?
它包括4月2日吗?
那要看谁能说“上个月”是从3月21日到4月20日。
有人可以说,从01.03到今天的“上个月”。
有人可以说,“上个月”从01.04开始。
有人可以说,“上个月”意味着整个游行,而不是4月的一天。
当“今天”接近月底时,尤其是在三月,它变得更加棘手。
不要因为自己读不懂写作业的人而对自己发硬;)
我写了一个查询,显示了不同的方法如何产生不同的结果。
CREATE OR REPLACE FUNCTION temp_can_subst_interval_months(p_date date, p_n_of_months number) RETURN NUMBER AS
V_date DATE;
BEGIN
V_Date := p_date - (NUMTOYMINTERVAL(p_n_of_months, 'month'));
RETURN 1;
EXCEPTION
WHEN OTHERS THEN
RETURN 0;
END;
with all_days as (
select to_date('2016-01-01', 'YYYY-MM-DD') + (level - 1) as d
from dual
connect by level < 1462
),
all_days_2 as (
select d date_of_query_being_run,
add_months(d, -40)as min_date_your_approach,
add_months(d, -40) + 1 as min_date_your_approach_2, -- same, but exclude the first day
trunc(add_months(d, -40), 'mm') as min_date_whole_month,
case when temp_can_subst_interval_months(d, 40) = 1 then
d - (interval '40' month)
else null
end as min_date_interval_approach
from all_days ad
order by ad.d
)
select ads.*
from all_days_2 ads
;
最有趣的结果是您的方法与间隔方法不同:
1 (sysdate) 2 (yours) 3 4 5 (interval) 31.01.2016 30.09.2012 01.10.2012 01.09.2012 29.02.2016 31.10.2012 01.11.2012 01.10.2012 29.10.2012 31.03.2016 30.11.2012 01.12.2012 01.11.2012 30.04.2016 31.12.2012 01.01.2013 01.12.2012 30.12.2012 29.06.2016 28.02.2013 01.03.2013 01.02.2013 30.06.2016 28.02.2013 01.03.2013 01.02.2013 31.08.2016 30.04.2013 01.05.2013 01.04.2013 30.09.2016 31.05.2013 01.06.2013 01.05.2013 30.05.2013 31.10.2016 30.06.2013 01.07.2013 01.06.2013 30.11.2016 31.07.2013 01.08.2013 01.07.2013 30.07.2013 31.01.2017 30.09.2013 01.10.2013 01.09.2013 28.02.2017 31.10.2013 01.11.2013 01.10.2013 28.10.2013 31.03.2017 30.11.2013 01.12.2013 01.11.2013 30.04.2017 31.12.2013 01.01.2014 01.12.2013 30.12.2013 29.06.2017 28.02.2014 01.03.2014 01.02.2014 30.06.2017 28.02.2014 01.03.2014 01.02.2014 31.08.2017 30.04.2014 01.05.2014 01.04.2014 30.09.2017 31.05.2014 01.06.2014 01.05.2014 30.05.2014 31.10.2017 30.06.2014 01.07.2014 01.06.2014 30.11.2017 31.07.2014 01.08.2014 01.07.2014 30.07.2014 31.01.2018 30.09.2014 01.10.2014 01.09.2014 28.02.2018 31.10.2014 01.11.2014 01.10.2014 28.10.2014 31.03.2018 30.11.2014 01.12.2014 01.11.2014 30.04.2018 31.12.2014 01.01.2015 01.12.2014 30.12.2014 29.06.2018 28.02.2015 01.03.2015 01.02.2015 30.06.2018 28.02.2015 01.03.2015 01.02.2015 31.08.2018 30.04.2015 01.05.2015 01.04.2015 30.09.2018 31.05.2015 01.06.2015 01.05.2015 30.05.2015 31.10.2018 30.06.2015 01.07.2015 01.06.2015 30.11.2018 31.07.2015 01.08.2015 01.07.2015 30.07.2015 31.01.2019 30.09.2015 01.10.2015 01.09.2015 28.02.2019 31.10.2015 01.11.2015 01.10.2015 28.10.2015 31.03.2019 30.11.2015 01.12.2015 01.11.2015 30.04.2019 31.12.2015 01.01.2016 01.12.2015 30.12.2015 30.06.2019 29.02.2016 01.03.2016 01.02.2016 31.08.2019 30.04.2016 01.05.2016 01.04.2016 30.09.2019 31.05.2016 01.06.2016 01.05.2016 30.05.2016 31.10.2019 30.06.2016 01.07.2016 01.06.2016 30.11.2019 31.07.2016 01.08.2016 01.07.2016 30.07.2016
旁注:
也许表格中包含“未来的预期销售量”之类的内容,并且他们希望您过滤出比sysdate晚的日期;)?