请问用sql实现通过已知的年,月,第几周和周几,得到具体的日期

请教用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

引用
Originally posted by lawolfgang at 2006-3-2 03:06 PM:
如何定义第几周?
每7天一周?oracle 这样计算。
周日是第一天?


看看Windows日历吧,周日是第一天!
summer.wang 发表于 2006-3-2 15:41

有select語句可以查出某個日期是一年裡面的第幾天,和一周裡面的第幾天的!
lawolfgang 发表于 2006-3-2 16:03

引用
Originally posted by sxxj at 2006-3-2 15:15:
看看Windows日历吧,周日是第一天!


谢谢。
:lihai我还真的看了又看。
select to_char( mydate, 'WW' ) form dual
select to_char( mydate, 'IW' ) form dual
的结果是不一样的。
还有在一周里,周日的序号是 1,而不是7。
lawolfgang 发表于 2006-3-2 16:14

希望对你有帮助.

    --        -------------------------
        --  一周里的第几个星期。
    --  周一是一周的第一天 。
        --
        function getWeekInMonth( p_date  DATE )
                return NUMBER
        is
                v_Result        number;
        v_No01      DATE;
        v_Month     NUMBER;
        begin
               
        --  本月的第一天。
        v_No01 := add_months( last_day( p_date ) + 1, -1 );
       
        WHILE TRUE Loop
            SELECT  to_number( to_char( v_No01, 'IW' ) ),
                    to_number( to_char( v_No01, 'MM' ) )
            INTO    v_Result,
                    v_Month
            FROM    dual;
           
            IF v_Month > 1 THEN     EXIT;
            END IF;
           
            IF v_Result = 52 THEN   v_No01 := v_No01 + 1;
            ELSE                    EXIT;
            END IF;
           
        END LOOP;
       
            --  一周里的第几个星期。
        SELECT  to_number( to_char( p_date, 'IW' ) ) -
                to_number( to_char( v_No01, 'IW' ) ) + 1
        INTO    v_Result
        FROM    dual;
                --
                return v_Result;
        end ;
   
        --        -------------------------
    --
    --  p_WeekDay   取值从1到7,依次对应周日、周一到周六。
    --
    --  SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
    --
    function getDate(
                        p_Year          IN      NUMBER,     --  年
                        p_Month         IN      NUMBER,     --  月
                        p_WeekNo        IN      NUMBER,     --  第几周
                        p_WeekDay       IN      NUMBER      --  周几,为了便于使用而使用数字。
                        )
        return date
    is
        v_First     DATE;
        v_Text      VARCHAR2( 20 );
        v_ActWeek   NUMBER;
    BEGIN
        IF p_WeekNo > 5 THEN        RETURN NULL;
        END IF;
       
        v_Text  := to_char( p_Year ) || '-' || to_char( p_Month ) || '-01';
        v_First := to_date( v_Text, 'yyyy-mm-dd' );
   
        WHILE TRUE Loop
            SELECT  NEXT_DAY( v_First, p_WeekDay )
            INTO    v_First
            FROM    dual    ;
               
            --  问题:下列语句异常??????
            --v_First := NEXT_DAY( v_First, 1 );
           
            v_ActWeek := getWeekInMonth( v_First );
           
            IF v_ActWeek = p_WeekNo THEN    EXIT;
            END IF;
           
            IF v_ActWeek > p_WeekNo THEN    v_First := NULL;
            END IF;
           
            IF v_ActWeek > p_WeekNo THEN    EXIT;
            END IF;
           
        END LOOP;
       
            RETURN  v_First ;
       
    end ;
sxxj 发表于 2006-3-2 18:08

直接用select to_char(sysdate,'W') from dual就可以查询出第几周了,为什么要用to_char(sysdate,'IW')?见笑了,IW参数没用过:)
lawolfgang 发表于 2006-3-2 18:36

引用
Originally posted by sxxj at 2006-3-2 18:08:
直接用select to_char(sysdate,'W') from dual就可以查询出第几周了,为什么要用to_char(sysdate,'IW')?见笑了,IW参数没用过:)


不好意思,让你见笑了. 请你仔细检查一下你的 SQL 运行结果.
'W' 的结果是从1号开始,每7天一个星期。7号一定在第一周。
但是2006-3-6 就是第二周了。你如何解释?
OK?
uni2046 发表于 2006-3-2 19:40

CREATE OR REPLACE
FUNCTION get_date ( y number, m number, w number, dow number)
RETURN DATE
IS
v_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>