标题:为庆祝我当选SQL版版主,发一些有用SQL语句.
只看楼主
潇洒老乌龟
Rank: 5Rank: 5
等 级:贵宾
威 望:18
帖 子:407
专家分:0
注 册:2005-12-13
得分:0 
日志文件损坏,如何恢复数据库

1.先建一个与你要恢复的数据库名称一样的数据库。
2.停止sql server,把你的数据库替换这个数据库。
3.重启sql server,把数据库设置为紧急状态。
sp_configure 'allow',1
reconfigure with overirde
update sysdatabases set status=32768 where name='yourdata'
4.重建日志文件。
dbcc rebuild_log('yourdata','your data path\newdata_log.ldf')
5.取消紧急模式。
update sysdatabases set status=0 where name='yourdata'
restore sysdatabases yourdata with recovery
sp_configure 'allow',0
reconfigure with override
6.重起sql server
7.ok

乌龟学堂http://www. 承接各种软件开发、系统集成、网络搭建。 QQ:124030710
2006-10-01 20:11
潇洒老乌龟
Rank: 5Rank: 5
等 级:贵宾
威 望:18
帖 子:407
专家分:0
注 册:2005-12-13
得分:0 

取n到m条记录的语句

1.
select top m * from tablename where id not in (select top n * from tablename)

2.
select top m * into 临时表(或表变量) from tablename order by columnname -- 将top m笔插入
set rowcount n
select * from 表变量 order by columnname desc

3.
select top n * from
(select top m * from tablename order by columnname) a
order by columnname desc


4.如果tablename里没有其他identity列,那么:
select identity(int) id0,* into #temp from tablename

取n到m条的语句为:
select * from #temp where id0 >=n and id0 <= m

如果你在执行select identity(int) id0,* into #temp from tablename这条语句的时候报错,那是因为你的DB中间的select into/bulkcopy属性没有打开要先执行:
exec sp_dboption 你的DB名字,'select into/bulkcopy',true


5.如果表里有identity属性,那么简单:
select * from tablename where identitycol between n and m


乌龟学堂http://www. 承接各种软件开发、系统集成、网络搭建。 QQ:124030710
2006-10-01 20:12
潇洒老乌龟
Rank: 5Rank: 5
等 级:贵宾
威 望:18
帖 子:407
专家分:0
注 册:2005-12-13
得分:0 

求group by后的sum以及第一条记录

id t1 t2 t3
a1 1 x1 aa
a1 2 b2 1b
a2 3 c3 3c
a2 4 q4 1d

group by id , t1求sum t2 t3求top 1

结果
a1 3 x1 aa
a2 7 c3 3c


create table test (id varchar(10),t1 int,t2 varchar(10),t3 varchar(10))
go
insert into test
select 'a1' , 1 , 'x1' , 'aa' union
select 'a1' , 2 , 'b2' , '1b' union
select 'a2' , 3 , 'c3' , '3c' union
select 'a2' , 4 , 'q4' , '1d'

select id,sum(t1) t1 ,
(select top 1 t2 from test B where B.Id=A.ID) t2 ,
(select top 1 t3 from test B where B.Id=A.ID) t3
from test A group by id

drop table test

id t1 t2 t3
---------- ----------- ---------- ----------
a1 3 x1 aa
a2 7 c3 3c

(所影响的行数为 2 行)


--使用如下一段语句也行。
select id ,
t1 = (select sum(t1) from test c where id=b.id),
t2,t3
from test b
where t1=(select top 1 t1 from test where id=b.id)


乌龟学堂http://www. 承接各种软件开发、系统集成、网络搭建。 QQ:124030710
2006-10-01 20:12
潇洒老乌龟
Rank: 5Rank: 5
等 级:贵宾
威 望:18
帖 子:407
专家分:0
注 册:2005-12-13
得分:0 

实现193.5转为一百玖拾叁元五角的存储过程

/********************************************************
作者:(birdie_7761@cmmail.com)
版本:1.0
创建时间:20020227
修改时间:
功能:小写金额转换成大写
参数:n_LowerMoney 小写金额
v_TransType 种类 -- 1: directly translate, 0: read it in words
输出:大写金额
********************************************************/
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[L2U]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[L2U]
GO

CREATE FUNCTION dbo.L2U(@n_LowerMoney numeric(15,2),@v_TransType int)
RETURNS VARCHAR(200) AS
BEGIN
Declare @v_LowerStr VARCHAR(200) -- 小写金额
Declare @v_UpperPart VARCHAR(200)
Declare @v_UpperStr VARCHAR(200) -- 大写金额
Declare @i_I int

set @v_LowerStr = LTRIM(RTRIM(ROUND(@n_LowerMoney,2))) --四舍五入为指定的精度并删除数据左右空格
set @i_I = 1
set @v_UpperStr = ''

while ( @i_I <= len(@v_LowerStr))
begin
select @v_UpperPart = case substring(@v_LowerStr,len(@v_LowerStr) - @i_I + 1,1)
WHEN '.' THEN '元'
WHEN '0' THEN '零'
WHEN '1' THEN '壹'
WHEN '2' THEN '贰'
WHEN '3' THEN '叁'
WHEN '4' THEN '肆'
WHEN '5' THEN '伍'
WHEN '6' THEN '陆'
WHEN '7' THEN '柒'
WHEN '8' THEN '捌'
WHEN '9' THEN '玖'
END
+
case @i_I
WHEN 1 THEN '分'
WHEN 2 THEN '角'
WHEN 3 THEN ''
WHEN 4 THEN ''
WHEN 5 THEN '拾'
WHEN 6 THEN '佰'
WHEN 7 THEN '仟'
WHEN 8 THEN '万'
WHEN 9 THEN '拾'
WHEN 10 THEN '佰'
WHEN 11 THEN '仟'
WHEN 12 THEN '亿'
WHEN 13 THEN '拾'
WHEN 14 THEN '佰'
WHEN 15 THEN '仟'
WHEN 16 THEN '万'
ELSE ''
END
set @v_UpperStr = @v_UpperPart + @v_UpperStr
set @i_I = @i_I + 1
end

if ( 0 = @v_TransType)
begin
set @v_UpperStr = REPLACE(@v_UpperStr,'零拾','零')
set @v_UpperStr = REPLACE(@v_UpperStr,'零佰','零')
set @v_UpperStr = REPLACE(@v_UpperStr,'零仟','零')
set @v_UpperStr = REPLACE(@v_UpperStr,'零零零','零')
set @v_UpperStr = REPLACE(@v_UpperStr,'零零','零')
set @v_UpperStr = REPLACE(@v_UpperStr,'零角零分','整')
set @v_UpperStr = REPLACE(@v_UpperStr,'零分','整')
set @v_UpperStr = REPLACE(@v_UpperStr,'零角','零')
set @v_UpperStr = REPLACE(@v_UpperStr,'零亿零万零元','亿元')
set @v_UpperStr = REPLACE(@v_UpperStr,'亿零万零元','亿元')
set @v_UpperStr = REPLACE(@v_UpperStr,'零亿零万','亿')
set @v_UpperStr = REPLACE(@v_UpperStr,'零万零元','万元')
set @v_UpperStr = REPLACE(@v_UpperStr,'万零元','万元')
set @v_UpperStr = REPLACE(@v_UpperStr,'零亿','亿')
set @v_UpperStr = REPLACE(@v_UpperStr,'零万','万')
set @v_UpperStr = REPLACE(@v_UpperStr,'零元','元')
set @v_UpperStr = REPLACE(@v_UpperStr,'零零','零')
end

-- 对壹元以下的金额的处理
if ( '元' = substring(@v_UpperStr,1,1))
begin
set @v_UpperStr = substring(@v_UpperStr,2,(len(@v_UpperStr) - 1))
end

if ( '零' = substring(@v_UpperStr,1,1))
begin
set @v_UpperStr = substring(@v_UpperStr,2,(len(@v_UpperStr) - 1))
end

if ( '角' = substring(@v_UpperStr,1,1))
begin
set @v_UpperStr = substring(@v_UpperStr,2,(len(@v_UpperStr) - 1))
end

if ( '分' = substring(@v_UpperStr,1,1))
begin
set @v_UpperStr = substring(@v_UpperStr,2,(len(@v_UpperStr) - 1))
end

if ('整' = substring(@v_UpperStr,1,1))
begin
set @v_UpperStr = '零元整'
end
return @v_UpperStr
END
GO

select dbo.L2U(12.93,1),dbo.L2U(12.93,0)


CREATE PROCEDURE dbo.L2U
(
@n_LowerMoney numeric(15,2),
@v_TransType int,
@RET VARCHAR(200) output
)
AS

Declare @v_LowerStr VARCHAR(200) -- 小写金额
Declare @v_UpperPart VARCHAR(200)
Declare @v_UpperStr VARCHAR(200) -- 大写金额
Declare @i_I int

set nocount On

select @v_LowerStr = LTRIM(RTRIM(STR(@n_LowerMoney,20,2))) --四舍五入为指定的精度并删除数据左右空格

select @i_I = 1
select @v_UpperStr = ''''

while ( @i_I <= len(@v_LowerStr))
begin
select @v_UpperPart = case substring(@v_LowerStr,len(@v_LowerStr) - @i_I + 1,1)
WHEN '.' THEN '元'
WHEN '0' THEN '零'
WHEN '1' THEN '壹'
WHEN '2' THEN '贰'
WHEN '3' THEN '叁'
WHEN '4' THEN '肆'
WHEN '5' THEN '伍'
WHEN '6' THEN '陆'
WHEN '7' THEN '柒'
WHEN '8' THEN '捌'
WHEN '9' THEN '玖'
END
+
case @i_I
WHEN 1 THEN '分'
WHEN 2 THEN '角'
WHEN 3 THEN ''
WHEN 4 THEN ''
WHEN 5 THEN '拾'
WHEN 6 THEN '佰'
WHEN 7 THEN '仟'
WHEN 8 THEN '万'
WHEN 9 THEN '拾'
WHEN 10 THEN '佰'
WHEN 11 THEN '仟'
WHEN 12 THEN '亿'
WHEN 13 THEN '拾'
WHEN 14 THEN '佰'
WHEN 15 THEN '仟'
WHEN 16 THEN '万'
ELSE''''
END
select @v_UpperStr = @v_UpperPart + @v_UpperStr
select @i_I = @i_I + 1
end

--------print '//v_UpperStr ='+@v_UpperStr +'//'

if ( @v_TransType=0 )
begin
select @v_UpperStr = REPLACE(@v_UpperStr,'零拾','零')
select @v_UpperStr = REPLACE(@v_UpperStr,'零佰','零')
select @v_UpperStr = REPLACE(@v_UpperStr,'零仟','零')
select @v_UpperStr = REPLACE(@v_UpperStr,'零零零','零')
select @v_UpperStr = REPLACE(@v_UpperStr,'零零','零')
select @v_UpperStr = REPLACE(@v_UpperStr,'零角零分','整')
select @v_UpperStr = REPLACE(@v_UpperStr,'零分','整')
select @v_UpperStr = REPLACE(@v_UpperStr,'零角','零')
select @v_UpperStr = REPLACE(@v_UpperStr,'零亿零万零元','亿元')
select @v_UpperStr = REPLACE(@v_UpperStr,'亿零万零元','亿元')
select @v_UpperStr = REPLACE(@v_UpperStr,'零亿零万','亿')
select @v_UpperStr = REPLACE(@v_UpperStr,'零万零元','万元')
select @v_UpperStr = REPLACE(@v_UpperStr,'万零元','万元')
select @v_UpperStr = REPLACE(@v_UpperStr,'零亿','亿')
select @v_UpperStr = REPLACE(@v_UpperStr,'零万','万')
select @v_UpperStr = REPLACE(@v_UpperStr,'零元','元')
select @v_UpperStr = REPLACE(@v_UpperStr,'零零','零')
end

-- 对壹元以下的金额的处理
if ( substring(@v_UpperStr,1,1)='元' )
begin
select @v_UpperStr = substring(@v_UpperStr,2,(len(@v_UpperStr) - 1))
end

if (substring(@v_UpperStr,1,1)= '零')
begin
select @v_UpperStr = substring(@v_UpperStr,2,(len(@v_UpperStr) - 1))
end

if (substring(@v_UpperStr,1,1)='角')
begin
select @v_UpperStr = substring(@v_UpperStr,2,(len(@v_UpperStr) - 1))
end

if ( substring(@v_UpperStr,1,1)='分')
begin
select @v_UpperStr = substring(@v_UpperStr,2,(len(@v_UpperStr) - 1))
end

if (substring(@v_UpperStr,1,1)='整')
begin
select @v_UpperStr = '零元整'
end

select @ret=@v_UpperStr

GO

--调用过程:

declare @ret varchar(200)

exec L2U 567983.897,1,@ret output

select @ret

CREATE FUNCTION [dbo].[f_num_chn] (@num numeric(14,2))
RETURNS varchar(100) WITH ENCRYPTION
AS
BEGIN
--版权所有:pbsql
DECLARE @n_data VARCHAR(20),@c_data VARCHAR(100),@n_str VARCHAR(10),@i int

SET @n_data=RIGHT(SPACE(14)+CAST(CAST(ABS(@num*100) AS bigint) AS varchar(20)),14)
SET @c_data=''
SET @i=1
WHILE @i<=14
BEGIN
SET @n_str=SUBSTRING(@n_data,@i,1)
IF @n_str<>' '
BEGIN
IF not ((SUBSTRING(@n_data,@i,2)='00') or
((@n_str='0') and ((@i=4) or (@i=8) or (@i=12) or (@i=14))))
SET @c_data=@c_data+SUBSTRING('零壹贰叁肆伍陆柒捌玖',CAST(@n_str AS int)+1,1)
IF not ((@n_str='0') and (@i<>4) and (@i<>8) and (@i<>12))
SET @c_data=@c_data+SUBSTRING('仟佰拾亿仟佰拾万仟佰拾圆角分',@i,1)
IF SUBSTRING(@c_data,LEN(@c_data)-1,2)='亿万'
SET @c_data=SUBSTRING(@c_data,1,LEN(@c_data)-1)
END
SET @i=@i+1
END
IF @num<0
SET @c_data='(负数)'+@c_data
IF @num=0
SET @c_data='零圆'
IF @n_str='0'
SET @c_data=@c_data+'整'
RETURN(@c_data)
END
GO


乌龟学堂http://www. 承接各种软件开发、系统集成、网络搭建。 QQ:124030710
2006-10-01 20:13
潇洒老乌龟
Rank: 5Rank: 5
等 级:贵宾
威 望:18
帖 子:407
专家分:0
注 册:2005-12-13
得分:0 

按表中ID分类统计再合并表数据

Food表中我加了一列Counter,这一列的值应该是在另外一个表中UserFood中Food.ID出现的次数,请问这个sql如何写.
我用这个select [ID],IsNULL((Select count(1) from UserFood where UserFood.FoodID = Food.ID),0) from Food,可以等到想要的值,但是不知道如何插入到Food表中.谢谢!!!

Food表
-------------
ID FoodName Counter
-------------
1 第一个 NULL
2 第二个 NULL
3 第三个 NULL


UserFood表
-------------
ID FoodID
-------------
1 1
2 2
3 1
4 1

想要的结果是:
Food表
-------------
ID FoodName Counter
-------------
1 第一个 3
2 第二个 1
3 第三个 0


create table food (id char(1),foodname varchar(10),counter int)
insert into food
select '1' , '第一个' , null union
select '2' , '第二个' , null union
select '3' , '第三个' , null

create table usefood (id char(1),foodid int)
insert into usefood
select '1' , 1 union
select '2' , 2 union
select '3' , 1 union
select '4' , 1


select a.id as id, a.foodname as foodname, isnull(b.counter, 0) as counter
from food as a left join (select foodid , count(*) as counter from usefood group by foodid) as b
on a.id = b.foodid

--select * from food
--select foodid , count(*) as counter from usefood group by foodid

drop table food
drop table usefood

id foodname counter
---- ---------- -----------
1 第一个 3
2 第二个 1
3 第三个 0

(所影响的行数为 3 行)


乌龟学堂http://www. 承接各种软件开发、系统集成、网络搭建。 QQ:124030710
2006-10-01 20:13
潇洒老乌龟
Rank: 5Rank: 5
等 级:贵宾
威 望:18
帖 子:407
专家分:0
注 册:2005-12-13
得分:0 

求一条追回序号的语句

如何简单来实现一条根据_id1,_id2的索引顺序,更新id的序号值,如下所述

如表
id _id1 _id2
null a c
null a d
null a f
null b c
null b e

执行后:

id _id1 _id2
1 a c
2 a d
3 a f
1 b c
2 b e

declare @tab table(id int,_id1 varchar(10),_id2 varchar(10))


insert @tab values(null,'a','e')
insert @tab values(null,'a','d')
insert @tab values(null,'a','f')
insert @tab values(null,'b','c')
insert @tab values(null,'b','e')

select * from @tab

select _id1,_id2,[排名]=(select count(1) from @tab where _id1=a._id1 and _id2<a._id2)+1 from @tab a
order by _id1,_id2

_id1 _id2 排名
---------- ---------- -----------
a d 1
a e 2
a f 3
b c 1
b e 2

(所影响的行数为 5 行)


乌龟学堂http://www. 承接各种软件开发、系统集成、网络搭建。 QQ:124030710
2006-10-01 20:14
潇洒老乌龟
Rank: 5Rank: 5
等 级:贵宾
威 望:18
帖 子:407
专家分:0
注 册:2005-12-13
得分:0 

如何将上月的数据插入到本月中

有一个表A.
有字段id,month,tbh,sfbs
id是自动编号
month是指月份,如200609
month有重复记录
现在想求一条语句,就是取出09月的数据全部取出,然后改成10月份再存到表A中,
要求会判断表中有没有10月份数据的存在,month+tbh+sfbs三个字段是唯一的数据

insert into A(month,tbh,sfbs)
select left(month,4)+'10',tbh,sfbs
from A
where right(month,2)='09'
where not exists (select 1 from A t where left(t.month,4)=left(a.month,4)
and a.tbh=t.tbh and a.sfbs=t.sfbs)


乌龟学堂http://www. 承接各种软件开发、系统集成、网络搭建。 QQ:124030710
2006-10-01 20:14
潇洒老乌龟
Rank: 5Rank: 5
等 级:贵宾
威 望:18
帖 子:407
专家分:0
注 册:2005-12-13
得分:0 

行列转换


SQL语句之普通行列转换

假设有张学生成绩表(tb_rowtocol)如下
Name Subject Result
张三 语文  73
张三 数学  83
张三 物理  93
李四 语文  74
李四 数学  84
李四 物理  94

想变成
姓名 语文 数学 物理
张三 73  83  93
李四 74  84  94

declare @sql varchar(4000)
set @sql = 'select Name as ' + '姓名'
select @sql = @sql + ' , sum(case Subject when '''+Subject+''' then Result end) ['+Subject+']'
from (select distinct Subject from rowtocol) as a
set @sql = @sql + ' from rowtocol group by name'
exec(@sql)

如果上述两表互相换一下:即
表名(cj)
姓名 语文 数学 物理
张三 73  83  93
李四 74  84  94

想变成

Name Subject Result
张三 语文  73
张三 数学  83
张三 物理  93
李四 语文  74
李四 数学  84
李四 物理  94

select 姓名 as Name,'语文' as Subject,语文 as Result from CJ union
select 姓名 as Name,'数学' as Subject,数学 as Result from CJ union
select 姓名 as Name,'物理' as Subject,物理 as Result from CJ
order by 姓名 desc


SQL语句之合并行列转换

  有表rowtocol,其数据如下:
  a b
  1 1
  1 2
  1 3
  2 1
  2 2
  3 1
  如何转换成如下结果:
  a b
  1 1,2,3
  2 1,2
  3 1

  创建一个合并的函数   

  create function f_rowtocol(@a int)
  returns varchar(8000)
  as
  begin
   declare @str varchar(8000)
   set @str = ''
   select @str = @str + ',' + cast(b as varchar) from rowtocol where a = @a
   set @str = right(@str , len(@str) - 1)
   return(@str)
  End
  go


  调用自定义函数得到结果:
  select distinct a ,dbo.f_rowtocol(a) from rowtocol


行列转换加合计

例如有表A某些人每月消费数据如下:
id data month
001 11 1
001 12 2
001 13 3
001 14 4
001 15 5
001 16 6
001 17 7
001 18 8
001 19 9
001 110 10
001 111 11
001 112 12
002 21 1
002 22 2
002 23 3
002 24 4
002 25 5
002 26 6
002 27 7
002 28 8
002 29 9
002 210 10
002 211 11
002 212 12
要实现如下结果:
人员 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
001 11 12 13 14 15 16 17 18 19 110 111 112
002 21 22 23 24 25 26 27 28 29 210 211 212

人员 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月 合计
001 11 12 13 14 15 16 17 18 19 110 111 112 468
002 21 22 23 24 25 26 27 28 29 210 211 212 858

第一个:

SELECT id as '人员' ,
SUM(CASE month WHEN 1 THEN data ELSE 0 END) AS '1月' ,
SUM(CASE month WHEN 2 THEN data ELSE 0 END) AS '2月' ,
SUM(CASE month WHEN 3 THEN data ELSE 0 END) AS '3月' ,
SUM(CASE month WHEN 4 THEN data ELSE 0 END) AS '4月' ,
SUM(CASE month WHEN 5 THEN data ELSE 0 END) AS '5月' ,
SUM(CASE month WHEN 6 THEN data ELSE 0 END) AS '6月' ,
SUM(CASE month WHEN 7 THEN data ELSE 0 END) AS '7月' ,
SUM(CASE month WHEN 8 THEN data ELSE 0 END) AS '8月' ,
SUM(CASE month WHEN 9 THEN data ELSE 0 END) AS '9月' ,
SUM(CASE month WHEN 10 THEN data ELSE 0 END) AS '10月' ,
SUM(CASE month WHEN 11 THEN data ELSE 0 END) AS '11月' ,
SUM(CASE month WHEN 12 THEN data ELSE 0 END) AS '12月'
FROM a
GROUP BY ID

第二个:

SELECT id as '人员' ,
SUM(CASE month WHEN 1 THEN data ELSE 0 END) AS '1月' ,
SUM(CASE month WHEN 2 THEN data ELSE 0 END) AS '2月' ,
SUM(CASE month WHEN 3 THEN data ELSE 0 END) AS '3月' ,
SUM(CASE month WHEN 4 THEN data ELSE 0 END) AS '4月' ,
SUM(CASE month WHEN 5 THEN data ELSE 0 END) AS '5月' ,
SUM(CASE month WHEN 6 THEN data ELSE 0 END) AS '6月' ,
SUM(CASE month WHEN 7 THEN data ELSE 0 END) AS '7月' ,
SUM(CASE month WHEN 8 THEN data ELSE 0 END) AS '8月' ,
SUM(CASE month WHEN 9 THEN data ELSE 0 END) AS '9月' ,
SUM(CASE month WHEN 10 THEN data ELSE 0 END) AS '10月' ,
SUM(CASE month WHEN 11 THEN data ELSE 0 END) AS '11月' ,
SUM(CASE month WHEN 12 THEN data ELSE 0 END) AS '12月' ,
SUM(data) as '合计'
FROM a
GROUP BY ID


表结构:
店面 产品 金额
--------------------------
A店 产品1 100
A店 产品2 100
A店 产品3 100
B店 产品1 200
B店 产品3 200
……
---------------------------
要求的结果是:
店面名称 产品1 产品2 产品3 …… 总计
A 100 100 100 …… 300
B 200 0 200 …… 400

这里产品数量不是固定的,店面也不是固定的
-----------------------------------
数据表里大约30万+的数据,
要怎么写这个存储过程能够使效率更高一些?

create table test(店面 varchar(10),产品 varchar(10),金额 int)
insert into test select 'A店','产品1',100
insert into test select 'A店','产品2',100
insert into test select 'A店','产品3',100
insert into test select 'B店','产品1',200
insert into test select 'B店','产品3',200
go

declare @sql varchar(8000)
set @sql='select 店面'
select @sql=@sql+','+产品+'=sum(case 产品 when '''+产品+''' then 金额 else 0 end)'
from test group by 产品 order by 产品
set @sql=@sql+',总计=sum(金额) from test group by 店面'
exec(@sql)
go

drop table test
go

店面 产品1 产品2 产品3 总计
---- ----- ----- ----- -----------
A店 100 100 100 300
B店 200 0 200 400


乌龟学堂http://www. 承接各种软件开发、系统集成、网络搭建。 QQ:124030710
2006-10-01 20:14
潇洒老乌龟
Rank: 5Rank: 5
等 级:贵宾
威 望:18
帖 子:407
专家分:0
注 册:2005-12-13
得分:0 

按日期统计的交叉表

表结构:
日期 用户ID 数量
2006.9.20 8 20
2006.9.1 10 20
2006.9.18 1 20
2006.9.1 5 20
2006.9.13 1 20
2006.9.14 3 20
2006.9.14 2 20
2006.9.20 7 20
2006.9.10 6 20
2006.9.20 1 20
统计结果为(按月按计,如统计9月数据)
日期 用户ID1, 用户ID2, 用户ID3....
1号 数据汇总 数据汇总 数据汇总
2号 数据汇总 数据汇总 数据汇总
3号 数据汇总 数据汇总 数据汇总
4号 数据汇总 数据汇总 数据汇总
5号 数据汇总 数据汇总 数据汇总
6号 数据汇总 数据汇总 数据汇总
7号 数据汇总 数据汇总 数据汇总
8号 数据汇总 数据汇总 数据汇总
9号 数据汇总 数据汇总 数据汇总


create table test(日期 datetime, 用户ID varchar(10) , 数量 int)
insert into test select '2006.9.20','8' ,20
insert into test select '2006.9.1' ,'10',20
insert into test select '2006.9.18','1' ,20
insert into test select '2006.9.1' ,'5' ,20
insert into test select '2006.9.13','1' ,20
insert into test select '2006.9.14','3' ,20
insert into test select '2006.9.14','2' ,20
insert into test select '2006.9.20','7' ,20
insert into test select '2006.9.10','6' ,20
insert into test select '2006.9.20','1' ,20
go

declare @sql varchar(8000)
set @sql=''
select @sql=@sql+',[用户ID'+rtrim(用户ID)+']=sum(case 用户ID when '+rtrim(用户ID)+' then 数量 else 0 end)' from test group by 用户ID order by 用户ID
set @sql='select datepart(dd,日期) as 日期' +@sql+' from test group by datepart(dd,日期) order by datepart(dd,日期)'

exec(@sql)

drop table test
go

日期 用户ID1 用户ID10 用户ID2 用户ID3 用户ID5 用户ID6 用户ID7 用户ID8
1 0 20 0 0 20 0 0 0
10 0 0 0 0 0 20 0 0
13 20 0 0 0 0 0 0 0
14 0 0 20 20 0 0 0 0
18 20 0 0 0 0 0 0 0
20 20 0 0 0 0 0 20 20


乌龟学堂http://www. 承接各种软件开发、系统集成、网络搭建。 QQ:124030710
2006-10-01 20:15
潇洒老乌龟
Rank: 5Rank: 5
等 级:贵宾
威 望:18
帖 子:407
专家分:0
注 册:2005-12-13
得分:0 

统计员工工作时间

现在有一个表(work)
字段
姓名(char),员工编号(int),时间(datetime),方向(cint)
说明
这是一个公司用来统计员工时间的表

员工上班时刷一下卡 系统就会往表里面添加一条新纪录记下
姓名 员工编号 上班时间 方向(0表示上班)

员工下班时刷一下卡 系统也会往表里面添加一条新纪录
姓名 员工编号 上班时间 方向(1表示上班)

现在的问题是我想统计每个员工的工作时间 怎么统计

--------------------------------------------------
PS:这个数据库结构不适我设计的

大家觉得能统计出时间来吗?

欢迎大家 积极发表意见 分不够可以加


写个简单的(一天只打卡二次,上班一次,下班一次):
declare @t table(姓名 char(10),员工编号 int,时间 datetime,方向 bit)
insert @t
select 'a',1,'2006-09-20 08:00:00',0 union all
select 'a',1,'2006-09-20 16:00:00',1 union all
select 'b',2,'2006-09-20 08:00:00',0 union all
select 'b',2,'2006-09-20 15:00:00',1 union all
select 'c',3,'2006-09-20 08:00:00',0 union all
select 'c',3,'2006-09-20 14:00:00',1 union all
select 'a',1,'2006-09-21 08:00:00',0 union all
select 'a',1,'2006-09-21 16:00:00',1 union all
select 'b',2,'2006-09-21 08:00:00',0 union all
select 'b',2,'2006-09-21 15:00:00',1 union all
select 'c',3,'2006-09-21 08:00:00',0 union all
select 'c',3,'2006-09-21 14:00:00',1
--select * from @t

SELECT a.员工编号,a.姓名,
日期 = convert(varchar(10),a.时间,112),
工作时间 = datediff(hh,a.时间,b.时间)
FROM @t as a
INNER JOIN @t as b
ON a.员工编号 = b.员工编号 and a.方向 = 0 and b.方向 = 1
WHERE datediff(dd,a.时间,b.时间) = 0

/*结果
员工编号 姓名 日期 工作时间
1 a 20060920 8
2 b 20060920 7
3 c 20060920 6
1 a 20060921 8
2 b 20060921 7
3 c 20060921 6
*/


乌龟学堂http://www. 承接各种软件开发、系统集成、网络搭建。 QQ:124030710
2006-10-01 20:15



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-93552-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.020924 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved