请教用sql实现通过已知的年,月,第几周和周几,得到具体的日期
请教用sql实现通过已知的年,月,第几周和周几,得到具体的日期
已知年,月,第几周和周几,
得到具体的日期?
xichenx 发表于 2006-3-2 11:20
顶上去,希望高手能看到
sxxj 发表于 2006-3-2 13:53
一个比较麻烦的方法:
DECLARE
I INT;
STR VARCHAR(20);
INPUT VARCHAR(20);
BEGIN
INPUT := &YYYY || LPAD(&MM, 2, '0') || &W || &D;
FOR I IN 1 .. 31 LOOP
SELECT TO_CHAR(TO_DATE(&YYYY || '-' || &MM || '-' || I), 'YYYYMMWD')
INTO STR
FROM DUAL;
IF STR = INPUT THEN
DBMS_OUTPUT.PUT_LINE(&YYYY || '-' || &MM || '-' || I);
EXIT;
END IF;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Input Error!');
END;
输入项中
yyyy——年
mm——月
w——第几周
d——周几的数字表示。(星期天=1,星期一=2,...)
lawolfgang 发表于 2006-3-2 15:06
如何定义第几周?
每7天一周?oracle 这样计算。
周日是第一天?
sxxj 发表于 2006-3-2 15:15
CREATE OR REPLACEFUNCTION get_date ( y number, m number, w number, dow number)RETURN DATEISv_w NUMBER;v_date DATE;BEGIN v_w := w; v_date := TO_DATE( y||'-'||m, 'YYYY-MM' ); IF dow < TO_CHAR(v_date, 'D') THEN v_w := v_w + 1; END IF; v_date := NEXT_DAY(v_date - 7, 'SUNDAY'); v_date := v_date + 7 * (v_w-1)+ dow-1; RETURN v_date;END;
y - 年份
m - 月
w - 周
dow - 星期, (1 = 星期日, 7=星期六)
uni2046 发表于 2006-3-2 19:45
WW : 年的一月一日第一周.
IW : 年的一月一日後第一星期一第一周. 所以 2005-1-1 是 2004 年的第53周.
sxxj 发表于 2006-3-3 10:52
引用Originally posted by lawolfgang at 2006-3-2 06:36 PM:
不好意思,让你见笑了. 请你仔细检查一下你的 SQL 运行结果.
'W' 的结果是从1号开始,每7天一个星期。7号一定在第一周。
但是2006-3-6 就是第二周了。你如何解释?
OK?
从Windows日历上看,2006-3-6不是第2周,而是第一周的周一,2006-3-7是第1周的周2,2006-3-8是第2周的周3,而2006-3-14才是第2周的周2。我对此的理解是:因为2006-3-1是第1周的周3,那么2006-3月的第1周的周日、周1、周2是多少呢?我认为是5、6、7。对了,这样解释比较清楚,2006-3-14是2006-3月的第2个星期2。
lawolfgang 发表于 2006-3-3 15:25
很遗憾,我不认为: “2006-3-6不是第2周,而是第一周的周一”。我依然认为: 2006-3-6是3月的第2周的周一。不过争论这个实在没有任何意义,一切有1楼说了算。
如果问题改变成为:
已知 ***某年某月的第n个星期w***,算出具体日期。问题可能就简单了。
<pre>
CREATE OR REPLACE FUNCTION get_date2(
y number,
m number,
idx number, -- 第几个n
dow NUMBER -- 星期 m
)
RETURN DATE
IS
v_date DATE;
v_cnt NUMBER := 0;
BEGIN
IF idx NOT BETWEEN 1 AND 5 THEN RETURN NULL;
END IF;
-- 上个月的最后一天.
v_date := TO_DATE( y || '-' || m, 'YYYY-MM' ) - 1;
WHILE TRUE LOOP
SELECT next_day( v_date , dow )
INTO v_date
FROM dual ;
v_cnt := v_cnt + 1;
IF idx = v_cnt THEN EXIT;
END IF;
END LOOP;
RETURN v_date;
END;
</pre>