现有员工打卡表:punch_card_record
字段:user_id,user_name,record_date(打卡日期 日期类型),onduty_time(上班时间 时间类型),
offduty_time(下班时间 时间类型)
user_id user_name record_date onduty_time offduty_time
001 张三 2009-01-02 08:55 17:21
002 李四 2009-01-02 09:00 17:40
003 王五 2009-01-02 08:58 17:19
001 张三 2009-01-03 08:47 17:23
002 李四 2009-01-03 08:40 17:44
003 王五 2009-01-03 09:03 17:29
001 张三 2009-01-04 09:19 17:28
002 李四 2009-01-04 08:50 17:10
003 王五 2009-01-04 08:54 17:26我想用语句实现
user_id user_name 2009-01-02 2009-01-03 2009-01-04 。。等等根据我给定的起止时间依次循环。
001 张三 √ √ √ √ △ √
002 李四 √ √ √ √ √ △
003 王五 √ △ △ √ √ √9:00---17:20之外的显示√ 其他显示 △以前问过一次,没有满意答案 可能没表达清楚。
字段:user_id,user_name,record_date(打卡日期 日期类型),onduty_time(上班时间 时间类型),
offduty_time(下班时间 时间类型)
user_id user_name record_date onduty_time offduty_time
001 张三 2009-01-02 08:55 17:21
002 李四 2009-01-02 09:00 17:40
003 王五 2009-01-02 08:58 17:19
001 张三 2009-01-03 08:47 17:23
002 李四 2009-01-03 08:40 17:44
003 王五 2009-01-03 09:03 17:29
001 张三 2009-01-04 09:19 17:28
002 李四 2009-01-04 08:50 17:10
003 王五 2009-01-04 08:54 17:26我想用语句实现
user_id user_name 2009-01-02 2009-01-03 2009-01-04 。。等等根据我给定的起止时间依次循环。
001 张三 √ √ √ √ △ √
002 李四 √ √ √ √ √ △
003 王五 √ △ △ √ √ √9:00---17:20之外的显示√ 其他显示 △以前问过一次,没有满意答案 可能没表达清楚。
一个办法是用decode或case when ... then ... else ... end
另一个办法就是用存储过程+循环+临时表;我看还是第二个方法好一些
user_name,
decode(to_char(record_date, 'dd'),
'01',
decode(sign((onduty_time -
To_Date(to_char(record_date, 'yyyy-mm-dd') ||
'09:00:00',
'yyyy-mm-dd hh24:mi:ss')) * 86400),
-1,
'△',
decode(sign((onduty_time -
To_Date(to_char(record_date, 'yyyy-mm-dd') ||
'17:20:00',
'yyyy-mm-dd hh24:mi:ss')) * 86400),
1,
'△','√'))) as '**-**-01'
from punch_card_record;
max(
case when
record_date=to_date('2009-01-02','yyyy-mm-dd')
and onduty_time >to_date('09:00','hh24:mi')
and onduty_time <to_date('17:20','hh24:mi')
then '△' else '√' end ),
max(
case when
record_date=to_date('2009-01-03','yyyy-mm-dd')
and onduty_time >to_date('09:00','hh24:mi')
and onduty_time <to_date('17:20','hh24:mi')
then '△' else '√' end ),
max(
case when
record_date=to_date('2009-01-03','yyyy-mm-dd')
and onduty_time >to_date('09:00','hh24:mi')
and onduty_time <to_date('17:20','hh24:mi')
then '△' else '√' end )
from punch_card_record
group by user_ID,user_name
天数少就这样写,天数多的话就用存储过程处理,对了我上面取别名时会出现错误,所以我没用别名,其它你自己处理吧
AS
type T_cursor is ref cursor;
end SysBasic;create or replace procedure GetEmpPunch_card(
v_begdate varchar,
v_enddate varchar,
c_cursor OUT SysBasic.T_cursor
)
is
cursor c_punch_card(v_begdate,v_enddate) is
select distinct record_date
from punch_card_record
where record_date between convert(date,v_begdate,'yyyy-mm-dd') end convert(date,v_enddate,'yyyy-mm-dd')
order by record_date;
strSql varchar2(4000);
begin
strSql := 'select a.user_id,a.user_name ';
for t_punch_card in c_punch_card(v_begdate,v_enddate) loop
strSql := strSql||',sum(case when a.record_date = t_punch_card.record_date and (a.onduty_time <= 9:00 or a.offduty_time >= 17:20) then 1 else 0 end) "'||t_punch_card.record_date||'"';
end loop;
strSql := strSql||' from punch_card_record a where a.record_date between convert(date,v_begdate,'yyyy-mm-dd') end convert(date,v_enddate,'yyyy-mm-dd') group by a.user_id,a.user_name'; open c_cursor for strSql;end GetEmpPunch_card;
注:结果中 1代表√,0代表△
SQL> var y number
SQL> exec :x:=to_date('2009-01-01','yyyy-mm-dd'); --开始时间
SQL> exec :y:=8; --查询8天内SELECT user_id, user_name, regexp_replace(translate(r, d, v), '[^√,△]+', '△')
FROM (SELECT user_id,
user_name,
REPLACE(wmsys.wm_concat(chr(record_date - :x + 1)), ',') d,
REPLACE(wmsys.wm_concat(CASE
WHEN onduty_time <= '09:00' AND offduty_time >= '17:20' THEN
'√'
ELSE
'△'
END),',') v
FROM punch_card_record
WHERE record_date BETWEEN :x AND :x + :y + 1
GROUP BY user_id, user_name) a,
(SELECT wmsys.wm_concat(chr(ROWNUM)) r FROM dual CONNECT BY ROWNUM <= :y);USER_ID USER_NAME REGEXP_REPLACE(TRANSLATE(R,D,V
------- ---------- --------------------------------------------------------------------------------
001 张三 △,√,√,△,△,△,△,△
002 李四 △,√,√,△,△,△,△,△
003 王五 △,△,√,△,△,△,△,△如果你坚持要不定列,那么:SQL> var x date
SQL> var y number
SQL> exec :x:=to_date('2009-01-01','yyyy-mm-dd'); --开始时间
SQL> exec :y:=8; --查询8天内
SELECT user_id,
user_name,
decode(instr(d,regexp_substr(r,'[^,]+',1,1)),0,'△','√') r1,
decode(instr(d,regexp_substr(r,'[^,]+',1,2)),0,'△','√') r2,
decode(instr(d,regexp_substr(r,'[^,]+',1,3)),0,'△','√') r3,
decode(instr(d,regexp_substr(r,'[^,]+',1,4)),0,'△','√') r4,
decode(instr(d,regexp_substr(r,'[^,]+',1,5)),0,'△','√') r5,
decode(instr(d,regexp_substr(r,'[^,]+',1,6)),0,'△','√') r6,
decode(instr(d,regexp_substr(r,'[^,]+',1,7)),0,'△','√') r7,
decode(instr(d,regexp_substr(r,'[^,]+',1,8)),0,'△','√') r8
FROM (SELECT user_id,
user_name,
wmsys.wm_concat(chr(record_date - :x + 1)) d,
wmsys.wm_concat(CASE
WHEN onduty_time <= '09:00' AND offduty_time >= '17:20' THEN
'√'
ELSE
'△'
END) v
FROM punch_card_record
WHERE record_date BETWEEN :x AND :x + :y +1
GROUP BY user_id, user_name) a,
(SELECT wmsys.wm_concat(chr(ROWNUM)) r FROM dual CONNECT BY ROWNUM <= :y);USER_ID USER_NAME R1 R2 R3 R4 R5 R6 R7 R8
------- ---------- -- -- -- -- -- -- -- --
001 张三 △ √ √ √ △ △ △ △
002 李四 △ √ √ √ △ △ △ △
003 王五 △ √ √ √ △ △ △ △
user_name,
decode(instr(d,regexp_substr(r,'[^,]+',1,1)),0,'△','√') r1,
decode(instr(d,regexp_substr(r,'[^,]+',1,2)),0,'△','√') r2,
decode(instr(d,regexp_substr(r,'[^,]+',1,3)),0,'△','√') r3,
decode(instr(d,regexp_substr(r,'[^,]+',1,4)),0,'△','√') r4,
decode(instr(d,regexp_substr(r,'[^,]+',1,5)),0,'△','√') r5,
decode(instr(d,regexp_substr(r,'[^,]+',1,6)),0,'△','√') r6,
decode(instr(d,regexp_substr(r,'[^,]+',1,7)),0,'△','√') r7,
decode(instr(d,regexp_substr(r,'[^,]+',1,8)),0,'△','√') r8
FROM (SELECT user_id,
user_name,
wmsys.wm_concat(chr(record_date - :x + 1)) d
FROM t
WHERE record_date BETWEEN :x AND :x + :y +1
AND onduty_time <= '09:00' AND offduty_time >= '17:20'
GROUP BY user_id, user_name) a,
(SELECT wmsys.wm_concat(chr(ROWNUM)) r FROM dual CONNECT BY ROWNUM <= :y);USER_ID USER_NAME R1 R2 R3 R4 R5 R6 R7 R8
------- ---------- -- -- -- -- -- -- -- --
001 张三 △ √ √ △ △ △ △ △
002 李四 △ √ √ △ △ △ △ △
003 王五 △ △ △ √ △ △ △ △