求SQL语句或数据库结构,帮忙提前者有分(200分)

  • 主题发起人 主题发起人 一成
  • 开始时间 开始时间

一成

Unregistered / Unconfirmed
GUEST, unregistred user!
现正在做一个工资管理系统,表结构内容如下
人员表(worker)
id name
1 张三
2 王二
工资项目表(payclass)
id payclass
1 基本工资
2 职位工资
3 医疗补助
工资表(pay)
id workerid payclassid pay
1 1 1 500
2 1 2 300
3 1 3 200
4 2 1 500
5 2 2 200
6 2 3 200

我想得到如下数据,如何去做?
姓名 基本工资 职位工资 医疗补助 合计
张三 500 300 200 1000
张三 500 200 200 900

请问这么做表结构有没有问题?如果有的话请指出,在线等待!
 
如果(payclass)
变了,那么想得到的数据是不是也发生改变?
 
你是否可以将payclass表中的记录作为表字段来处理。使用ALTER TABLE 来不断的修改结构。
 
我觉得这个结构就可以了
select a.id,a.name,sum( case when payclassid=1 then pay else 0 end),
sum( case when payclassid=2 then pay else 0 end),
sum( case when payclassid=3 then pay else 0 end)
from a,b on a.id=b.wokerid
group by a.id,a.name
 
select a.Name,b.pay 基本工资,c.pay 职位工资,d.pay 医疗补助,b.pay+c.Pay+d.Pay 合计
from worker a,
(select nvl(sum(bb.pay),0),bb.workerid from payclass aa,pay bb where aa.id=bb.id and aa.id=1 group by bb.workid)b,
(select nvl(sum(bb.pay),0),bb.workerid from payclass aa,pay bb where aa.id=bb.id and aa.id=2 group by bb.workid)c,
(select nvl(sum(bb.pay),0),bb.workerid from payclass aa,pay bb where aa.id=bb.id and aa.id=3 group by bb.workid)d

where a.id=b.workid and a.id=c.workid and a.id=d.workid

sqlserver 的话 把nvl ()函数换成 IsNull ()函数
 
如果“工资项目表”是不定长的,就用游标吧
 
谢谢大家的回复
payclass表中的数据是不固定的,有可能多也有可能少
我估计用一句sql实现的可能性很小,能否用delphi+sql语句来实现?
 
你的结构是合理的,
一般都需要工资项目表,因为工资项目会变化
根据工资项目表生成工资表
工资项目表就相当于一个控制表或者说明表一样的
我们也是这么做的
 
一般都是这样做的。
 
你的结构是合理的,要生成你那样的结果的话,我觉得要用循环(或插入临时表),
其实,这就是一个行列转换的问题。
 
用循环(或插入临时表)?

可否给出具体代码 
 
表结构没错,要用游标来写
 
估计你看不懂(因为TABLE结构你不知道),这是我实际用的代码。

DMPc.cdsVbnOutFutrue.DisableControls;
DMPc.cdsVbnOutFutrue.First;
strTempStyle:='';
irow:=1;
while not DMPc.cdsVbnOutFutrue.Eof do
begin
strStyle:=trim(DMPc.cdsVbnOutFutrue['styleNo']);
if strStyle<>strTempStyle then
begin
strTempStyle:=strStyle;
inc(irow);
if trim(DMPc.cdsVbnOutFutrue['IsNewStyle']) <> 'N' then
begin
sgdResult.Cells[0,irow-1]:=strStyle+'-New';
F1Book1.EntryRC[irow,1]:=strStyle+'-New';
end
else
begin
sgdResult.Cells[0,irow-1]:=strStyle;
F1Book1.EntryRC[irow,1]:=strStyle;
end;
end;

DecodeDate(DMPc.cdsVbnOutFutrue[strDateCol], Year, Month, Day);
icol:=FindColNum(iColCount,Day);
if icol<>-1 then // 返回值是-1说明没有找到
begin
if trim(F1Book1.EntryRC[irow,icol+1])='' then
F1Book1.EntryRC[irow,icol+1]:=inttostr(DMPc.cdsVbnOutFutrue['InstQty'])+' '+DMPc.cdsVbnOutFutrue['instNo']
else
F1Book1.EntryRC[irow,icol+1]:=F1Book1.EntryRC[irow,icol+1]+' '+
inttostr(DMPc.cdsVbnOutFutrue['InstQty'])+' '+DMPc.cdsVbnOutFutrue['instNo'] ;
sgdResult.Cells[icol,irow-1]:=F1Book1.EntryRC[irow,icol+1];
end;
DMPc.cdsVbnOutFutrue.Next;
end; // while not DMPc.cdsVbnOutFutrue.Eof do
DMPc.cdsVbnOutFutrue.First;
DMPc.cdsVbnOutFutrue.EnableControls;
 
不瞒大虾,我真的没看懂:)
 
是什么数据库,我来写一个
 
用游标可以实现,最终插入临时表中,sql server版:
declare @creTable varchar(1000)
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[tempTalbe]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[tempTable]
set @creTable='CREATE TABLE [dbo].[tempTable] ( [WorkeriD] [varchar] (6) not null'
declare @payId varchar[10],@colNum int
declare pay_cur cursor for select distinct payClassId from pay order by payClassId
open pay_cur
fetch pay_cur into @payId
set @colNum=1
while @@fetch_status=0
begin
set @createTable=@createTable+',['+@payId+'] [decimal] (9,2) Null'
fetch pay_cur into @payId
set @colNum=@colNum+1
end
close pay_cur
deallocate pay_cur
if @colNum=1 return
exec (@CreateTable)
--此时已经创建了临时表,表结构为:员工编号,工资项目1、工资项目2、。。。。。一工资项目编号为列名称
declare @workerId varchar(6),@pay decimal(9,2),@sql varchar(300)
declare pay_detail cursor for select workerId,payClassId,pay from pay
open pay_detial
fetch pay_detail into @workerId,@payId,@pay
while @@fetch_status=0
begin
if not exists(select * from tempTable where workerId=@workerId)
begin
set @sql='insert into tempTable(workerid,'+@payId+') values('+@workerId+','+@pay+')'
end
else
begin
set @sql='update tempTable set '+@payId+'='+@pay+' where workerId='+@workerId
end
exec (@sql)
fetch pay_detail into @workerId,@payId,@pay
end
close pay_detail
deallocate pay_detail

写完了,好累,现在select * from tempTable应该可以了
不过很麻烦,需要稍加调试,大致思路就是这样的,我想应该能够实现
另外,这种设计会增加查询和汇总的时间的,我以前所做的设计是把工资表中
的工资项目预设30或者40个,再用一个表来对应工资向目和工资表中的对应
查询统计汇总等操作应该比你的设计快一些---愚见,见笑了
 
其实我的思路和zhangfu_mail 是一样的,但我一直没有找到行列高效率转换的方法。。。
 
多人接受答案了。
 
后退
顶部