關于算工資時一個 sql 問題,大家幫幫忙,(灌水分300) (答中的300)(300分)

  • 主题发起人 主题发起人 lqy169
  • 开始时间 开始时间
L

lqy169

Unregistered / Unconfirmed
GUEST, unregistred user!
問題出在 工資變動時 比如 算一月份的工資,工資表記錄如下

員工 基本工資 啟用時間
A 1000 2001/12/1
B 900 2001/8/1
B 1000 2002/1/15

算 2002/1/1-2002/1/31的工資
A 的不用多說是 1000
B 的
1 - 14 號親每天 900/30
15- 31 號是每天 1000/30

請問我怎么樣在存儲過程中﹐用最簡單的方法得到這個結果






 
用临时表结合游标很容易做的。
 
可能要用游标做了
应该不难做啊
 
請給段例子
 
case when 启用时间<'2002-01-01' then 工资=基本工资
when 启用时间>'2002-01-31' then 工资=0
else

 
我也關注,看看風聲。
 
帮你提前
 
// 用这段代码基本上可以把你的要求体现出来了。最后的结果为lastvalue,
//用两个数组分别记录时间,和工资的值,而且是按照小到大的顺序。所以
//把时间数组i+1的时间减去时间数组i的时间再乘基本工资数组i的值
//我想大概的思路应该是正确的,其中有些sql语句相应的该该就可以了。
//不好意思,我的回答可能不是你最终想要的,不过道理应该一样的。
//不知道这是否你要的答案,反正我是发了一段时间了。祝你成功!
var
name:string;
lastvalue,recordnum,i:integer;
recordtime:array [0..30]of Tdatatime;
recordvalue:array [0..30]of integer;
begin//1
i:=0;
query1.close;
query1.sql.clear;
query1.sql.add('select 员工 from 工资表 group by 员工 where 启用时间 between 2002/1/1 to 2002/1/31');
query1.open;
if query1.recordcount>0 then
begin//2
query1.first;
while not query1.eof do
begin//3
name:=query1.fieldvalues['员工'];
query2.close;
query2.sql.clear;
query2.sql.add('select * from 工资表 where (员工=name) and (启用时间 between 2002/1/1 to 2002/1/31) order by 启用时间 ');
query2.open;
if query2.recordcount>0 then
begin//4
query2.first;
recordnum:=query2.recordcount;
if recordnum=1 then //这段时间里基本工资没变化
begin//5
......//应该知道怎么做吧。
end //5
else //这段时间里基本工资有变化
begin //6
while i<recordnum do
begin //7
recordtime:=query2.fieldvalues['启用时间'];
recordvalue:=query2.fieldvalues['基本工资'];
i:=i+1;
query2.next;
end;//7
recordtime[i+1]:=2002/1/31; //再加上月底的时间
recordvalue[i+1]:=query2.fieldvalues['基本工资'];//最后的基本工资
if (i+2) mod 2<>0 then //如果数组的个数从0到i+1,不是偶数的话,
begin //8 再增加一条同样数组。这样下面的相减不出错。
recordtime[i+2]:=2002/1/31;
recordvalue[i+2]:=query2.fieldvalues['基本工资'];
recordnum:=i+2;
end //8
else
begin //9
recordnum:=i+1;
end; //9
i:=0;
while i<recordnum do
begin //10
lastvalue:=lastvalue+(recordtime[i+1]-recordtime)*recordvalue;
i:=i+1; //这就是每位员工的工资
end; //10
end; //6
end; //4
query1.next;
end; //3
end; //2
end;//1
 
2002/1/1-2002/1/31
SQL SERVER: B的
select 900 from table1 where DATEPART(d,启用时候)<15
union
select 1000 from table1 where DATEPART(d,启用时候)>=15
 
试试吧,应该没问题,我花了近两个小时专门为你编写的
Table1为你设置的表(员工,基本工资,启用日期)
Table2是我建立的新表(年月,员工,基本工资),是为了保存员工某月的实际基本工资用的.
Usage: exec 算基本工资 '200201','2002-01-01','2002-01-31' (不用说明你都能明白的了)

CREATE PROCEDURE [算基本工资] (@month nvarchar(4) ,@date1 nvarchar(10),@date2 nvarchar(10))
AS
declare @no nvarchar(10),@gz money
declare @startdate datetime,@jbgz money
declare @days1 int, @days2 int

-- 先删除已经算号的基本工资,为重新计算做准备
delete from table2 where 年月=@month

declare 员工清单 cursor for select distinct 员工 from table1 order by 员工
open 员工清单
fetch next from 员工清单 into @no
while (@@fetch_status<>-1)
begin
select @gz=0
declare 基本工资变动表 SCROLL cursor for
select 启用日期,基本工资 from table1 where 员工=@no order by 启用日期 desc
open 基本工资变动表
fetch next from 基本工资变动表 into @startdate,@jbgz
while (@@fetch_status<>-1)
begin
if @startdate<@date1 -- 本月的开始日期小于此员工最近的基本工资设置日期
begin
select @gz=@jbgz
fetch last from 基本工资变动表 into @startdate,@jbgz
-- exit
end
if @startdate>@date2 ---- 本月的结束日期大于此员工最近的基本工资设置日期
begin
select @gz=0
end
if @startdate=@date1 ---- 本月的开始日期等于此员工最近的基本工资设置日期
begin
select @gz=@jbgz
fetch last from 基本工资变动表 into @startdate,@jbgz
-- exit
end

if ((@startdate>@date1) and (@startdate<=@date2)) ---- 此员工最近的基本工资设置日期落在本月日期范围内
begin
select @days1=DATEDIFF(DAY,@date1,@startdate)
select @days2=DATEDIFF(DAY,@startdate,@date2)
select @gz=@days1*round(@jbgz/30,2)

select @jbgz=基本工资 from table1
where 启用日期=(select max(t1.启用日期) from table1 t1 where t1.员工=@no and t1.启用日期<@startdate)
select @gz=@gz+@days2*round(@jbgz/30,2)

fetch last from 基本工资变动表 into @startdate,@jbgz
-- exit
end

fetch next from 基本工资变动表 into @startdate,@jbgz
end
close 基本工资变动表
deallocate 基本工资变动表

insert into table2(年月,员工,基本工资) values(@month,@no,@gz)
fetch next from 员工清单 into @no

end

close 员工清单
deallocate 员工清单


 
參考以下:
以下程式在SQl Server Query Analyzer環境下調試成功。
if exists (select name from tempdb..sysobjects where name like '%#temp10%')
drop table #temp10
Select 員工,當月工資=0 into #temp10 from Table10 group by 員工
declare @begindate datetime /*輸入算工資開始時間*/
declare @enddate datetime /*輸入算工資結束時間*/
select @begindate=convert(datetime,'2002/01/01')
select @enddate=convert(datetime,'2002/01/31')
declare #cursor1 cursor for select 員工 from #temp10 order by 員工
open #cursor1
declare @name1 varchar(10)
fetch next from #cursor1 into @name1
while @@fetch_status=0
begin
declare @date1 datetime
select @date1=max(啟用時間) from table10 where 員工=@name1
if @date1<=@begindate /*最大啟用時間小于或等于計算工資開始時間*/
update #temp10 set 當月工資=(select 基本工資 from table10 where 員工=@name1 and 啟用時間=@date1) where 員工=@name1
else
begin
select @date1=min(啟用時間) from table10 where 員工=@name1
if @date1<=@enddate
begin
select @date1=max(啟用時間) from table10 where 員工=@name1 and 啟用時間<=@begindate
declare @quan float
select @quan=0
declare @quan01 float
declare @date01 datetime
declare #cursor2 cursor for
select 基本工資,啟用時間 from table10 where 啟用時間>=@begindate and 啟用時間<=@enddate and 員工=@name1 order by 啟用時間
open #cursor2
fetch next from #cursor2 into @quan01,@date01
if @date1=null
select @date1=@date01
else
select @date1=@begindate
while @@fetch_status=0
begin
declare @day integer
select @day=datediff(day,@date1,@date01) /*啟用時間之間相差天數*/
select @quan=@quan+@quan01*@day/30
print @quan
select @date1=@date01
fetch next from #cursor2 into @quan01,@date01

end
close #cursor2
deallocate #cursor2
select @day=datediff(day,@date01,@enddate)
select @quan=@quan+@quan01*@day/30

update #temp10 set 當月工資=@quan where 員工=@name1
end
/*最小啟用時間大于計算工資結束時間,不算工資*/
end
fetch next from #cursor1 into @name1
end
close #cursor1
deallocate #cursor1
select * from #temp10 /*顯示的就是當月工資情況*、
 
我本想给你写 一个
还好没有写
要不
300分这么多人分
 
非常感謝大家的幫助﹐本來我是想出點分,偷偷懶的,最好是等到高手的神來之筆
﹐不過昨晚大家都還沒貼上來,老板就逼我寫出來了。
看了看大家的貼子﹐思路都正確﹐zxb200 的最好,但還是沒考慮到 在算 1 月份工資時
有 2001/3/1 的調薪記錄 luoyy2000的沒考慮到中間有多次 調薪,吴事生飞沒看我的題
現在分分啦

zxb200 luoyy2000 請到
http://www.delphibbs.com/delphibbs/dispq.asp?lid=970292 分分
 
后退
顶部