SQL server基础代码整理

代码来源:论坛搜集

 

问题1:现有两个表TB1,TB2,有如下数据


TB1
FD    SP
A    111
B    222
C    222
D    333
E    333
.    ...

TB2
SP
111
222
333
...
我想把TB2表的数据插入到TB1表,TB1.FD每个值都要有TB2.SP的值,但不要重复插入
结果如下
TB1
FD  SP
A    111
A    222
A    333
B    111
B    222
B    333
... 

 

代码1:

if object_id('tb1') is not null drop table tb1
go
create table tb1([FD] varchar(10),[SP] int)
insert tb1 select 'A',111
union all select 'B',222
union all select 'C',222
union all select 'D',333
union all select 'E',333
go
if object_id('tb2') is not null drop table tb2
go
create table tb2([SP] int)
insert tb2 select 111
union all select 222
union all select 333
go

insert tb1
select *
from (Select * from (select distinct fd from tb1) a,tb2) as t
where not exists(select 1 from tb1 where fd=t.fd and sp=t.sp)

select * from tb1 order by fd

 

代码2:

create table #Tb1(FD nvarchar(2), sp nvarchar(10))
insert #tb1 values('A'    ,'111')
insert #tb1 values('B'    ,'222')
insert #tb1 values('C'    ,'222')
insert #tb1 values('D'    ,'333')
insert #tb1 values('E'    ,'333')


create table #Tb2(Sp nvarchar(10))
insert #tb2 values('111')
insert #tb2 values('222')
insert #tb2 values('333')

insert #tb1
select a.FD,b.sp from #tb1 a join #tb2 b on a.sp <> b.sp
order by a.fd

select * from #tb1 order by fd,sp

 

代码3:

create table #tb1([FD] varchar(10),[SP] int)
insert #tb1 select 'A',111
union all select 'B',222
union all select 'C',222
union all select 'D',333
union all select 'E',333
go

create table #tb2([SP] int)
insert #tb2 select 111
union all select 222
union all select 333
go

insert into #tb1 select * from
(
 
select b1.FD,b2.sp as sp2 from #tb1 b1,#tb2 b2 where b1.[SP] not in (b2.[SP])
)T

select * from #tb1  order by FD,[SP]

 

 

问题2:

 

一个元器件表,向表中添加元器件,若表中已有,则不添加,若没有,则添加并自动编号。元器件属性有:名称,类型,封装方式,这三个属性有一个不一样就代表是新的一个元器件。自动编号是指:找出一个分类中的最大编号,如“电阻类”,最大编号R0010,则新加的自动编号为R0011。根据问题描述,编写一个存储过程。

 

代码一:

create proc pr_test
@name varchar(20),
@type varchar(10),
@package varchar(10)
as
begin
   
if not exists(select 1 from [device] where [name] = @name and [type] = @type and package = @package)
   
begin
       
declare @maxid varchar(100)

select @maxid = max(id) from [device] where [type] = @type
       
set @maxid = left(@maxid,1)+ right('0000'+ltrim(cast(stuff(@maxid,1,1,'') as int) + 1),4
       
insert [device] select @maxid,@name,@type,@package
   
end
end

其中:left(character_expression,integer_expression):返回从字符串左边开始指定个数的字符;

         RIGHT(character_expression,integer_expression):返回从字符串右边开始指定个数的字符;

         ltrim(character_expression):删除起始空格后返回字符串表达式;

         cast(<expression> as <data_type> [length]):用以转换数据类型;

         stuff(<character_expression1>,<start_position>,<length>,<charavter_expression2>):用另一子串代替字符串指定位置、长度的子串,(如果起始位置或长度值为负,或者起始位置大于表达式1的长度,择返回null,如果长度大于表达式1中起始位置以右的长度,则表达式1只保留首字符);

 

代码2:

--用触发器也可以。
--
假定元器件表为yqjb
create trigger trig_insert_yqjb on yqjb
instead
of  insert as
declare @no varchar(10)
if not exists(select 1 from inserted a,yqjb b where a.名称=b.名称 and a.类型=b.类型 and a.封装方式=b.封装方式)
begin
       set  @no=(select max(编号) from yqjb where 类型 in (select 类型 from inserted))
       set @no=left(@no,1)+right('0000'+ltrim(cast(right(@no,4) as int)+1),4)
       insert yqjb(编号,名称,类型,封装方式) select @no,名称,类型,封装方式 from inserted
end

代码3:

create proc INSERT_DATA
@name varchar(20),
@type varchar(10),
@package varchar(10)
as
begin
    if not exists(select 1 from 表 where 名称 = @name and 类型 = @type and 封装方式 = @package)
    begin
        declare @maxID varchar(100)
        declare @nextID varchar(100)
set @maxID=''
        set @nextID=''
        select @maxID = max([自动ID号]) from 表 where 类型 = @type
        set @nextID = left(@maxID,1)
        set @maxID=convert(varchar(10),(convert(int,right(@maxID,len(@maxID)-1))+1))
        if len(@maxID)=3 set @maxID="0"+@maxID
        if len(@maxID)=2 set @maxID="00"+@maxID
        if len(@maxID)=1 set @maxID="000"+@maxID
        set @nextID=@nextID+@maxID
        insert into 表 select @nextID,@name,@type,@package
    end
end

说明:上面代码只复制了表的结构,不复制表内容。这种代码在需要建很多结构相同的表的时候很有用。

 

问题3

假如表a已经存在,现在要建一个新表,其表结构和其中的字段名称、属性都与表a相同,只有表名不同。则可以采用以下代码完成表结构的复制。

select   *   into   b   from   a   where   1<>1  

或者:select top 0 * into b from a

 

问题4:某表有一个时间字段Sdt,要按照时间字段查找表中最后一条记录。代码如下:

         SELECT TOP 1 * FROM TB ORDER BY Sdt DESC

 

问题5:要查找表中指定的第n至m条记录,参考代码如下:

N-M条记录
1.
select top m * into 临时表(或表变量) from tablename order by columnname -- 将top m笔插入

set rowcount n
select * from 表变量 order by columnname desc

set rowcount  0


2.
select top n * from

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



3.
如果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

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

问题5:处理重复的记录(查询和删除)

 /******************************************************************************************************************************************************
1、Num、Name相同的重复值记录,没有大小关系只保留一条
2、Name相同,ID有大小关系时,保留大或小其中一个记录
整理人:中国风(Roy)

日期:2008.06.06
*****************************************************************************************************************************************************
*/

--1、用于查询重复处理记录(如果列没有大小关系时2000用生成自增列和临时表处理,SQL2005用row_number函数处理)

--> --> (Roy)生成測試數據

if not object_id('Tempdb..#T') is null
   
drop table #T
Go
Create table #T([ID] int,[Name] nvarchar(1),[Memo] nvarchar(2))
Insert #T
select 1,N'A',N'A1' union all
select 2,N'A',N'A2' union all
select 3,N'A',N'A3' union all
select 4,N'B',N'B1' union all
select 5,N'B',N'B2'
Go


--I、Name相同ID最小的记录(推荐用1,2,3),方法3在SQl05时,效率高于1、2
方法1:
Select * from #T a where not exists(select 1 from #T where Name=a.Name and ID<a.ID)

方法2:
select a.* from #T a join (select min(ID)ID,Name from #T group by Name) b on a.Name=b.Name and a.ID=b.ID

方法3:
select * from #T a where ID=(select min(ID) from #T where Name=a.Name)

方法4:
select a.* from #T a join #T b on a.Name=b.Name and a.ID>=b.ID group by a.ID,a.Name,a.Memo having count(1)=1

方法5:
select * from #T a group by ID,Name,Memo having ID=(select min(ID)from #T where Name=a.Name)

方法6:
select * from #T a where (select count(1) from #T where Name=a.Name and ID<a.ID)=0

方法7:
select * from #T a where ID=(select top 1 ID from #T where Name=a.name order by ID)

方法8:
select * from #T a where ID!>all(select ID from #T where Name=a.Name)

方法9(注:ID为唯一时可用):
select * from #T a where ID in(select min(ID) from #T group by Name)

--SQL2005:

方法10:
select ID,Name,Memo from (select *,min(ID)over(partition by Name) as MinID from #T a)T where ID=MinID

方法11:

select ID,Name,Memo from (select *,row_number()over(partition by Name order by ID) as MinID from #T a)T where MinID=1

生成结果:
/*
ID          Name Memo
----------- ---- ----
1           A    A1
4           B    B1

(2 行受影响)
*/


--II、Name相同ID最大的记录,与min相反:
方法1:
Select * from #T a where not exists(select 1 from #T where Name=a.Name and ID>a.ID)

方法2:
select a.* from #T a join (select max(ID)ID,Name from #T group by Name) b on a.Name=b.Name and a.ID=b.ID order by ID

方法3:
select * from #T a where ID=(select max(ID) from #T where Name=a.Name) order by ID

方法4:
select a.* from #T a join #T b on a.Name=b.Name and a.ID<=b.ID group by a.ID,a.Name,a.Memo having count(1)=1

方法5:
select * from #T a group by ID,Name,Memo having ID=(select max(ID)from #T where Name=a.Name)

方法6:
select * from #T a where (select count(1) from #T where Name=a.Name and ID>a.ID)=0

方法7:
select * from #T a where ID=(select top 1 ID from #T where Name=a.name order by ID desc)

方法8:
select * from #T a where ID!<all(select ID from #T where Name=a.Name)

方法9(注:ID为唯一时可用):
select * from #T a where ID in(select max(ID) from #T group by Name)

--SQL2005:

方法10:
select ID,Name,Memo from (select *,max(ID)over(partition by Name) as MinID from #T a)T where ID=MinID

方法11:
select ID,Name,Memo from (select *,row_number()over(partition by Name order by ID desc) as MinID from #T a)T where MinID=1

生成结果2:
/*
ID          Name Memo
----------- ---- ----
3           A    A3
5           B    B2

(2 行受影响)
*/



--2、删除重复记录有大小关系时,保留大或小其中一个记录


--> --> (Roy)生成測試數據

if not object_id('Tempdb..#T') is null
   
drop table #T
Go
Create table #T([ID] int,[Name] nvarchar(1),[Memo] nvarchar(2))
Insert #T
select 1,N'A',N'A1' union all
select 2,N'A',N'A2' union all
select 3,N'A',N'A3' union all
select 4,N'B',N'B1' union all
select 5,N'B',N'B2'
Go

--I、Name相同ID最小的记录(推荐用1,2,3),保留最小一条
方法1:
delete a from #T a where  exists(select 1 from #T where Name=a.Name and ID<a.ID)

方法2:
deletefrom #T a left join (select min(ID)ID,Name from #T group by Name) b on a.Name=b.Name and a.ID=b.ID where b.Id is null

方法3:
delete a from #T a where ID not in (select min(ID) from #T where Name=a.Name)

方法4(注:ID为唯一时可用):
delete a from #T a where ID not in(select min(ID)from #T group by Name)

方法5:
delete a from #T a where (select count(1) from #T where Name=a.Name and ID<a.ID)>0

方法6:
delete a from #T a where ID<>(select top 1 ID from #T where Name=a.name order by ID)

方法7:
delete a from #T a where ID>any(select ID from #T where Name=a.Name)



select * from #T

生成结果:
/*
ID          Name Memo
----------- ---- ----
1           A    A1
4           B    B1

(2 行受影响)
*/


--II、Name相同ID保留最大的一条记录:

方法1:
delete a from #T a where  exists(select 1 from #T where Name=a.Name and ID>a.ID)

方法2:
deletefrom #T a left join (select max(ID)ID,Name from #T group by Name) b on a.Name=b.Name and a.ID=b.ID where b.Id is null

方法3:
delete a from #T a where ID not in (select max(ID) from #T where Name=a.Name)

方法4(注:ID为唯一时可用):
delete a from #T a where ID not in(select max(ID)from #T group by Name)

方法5:
delete a from #T a where (select count(1) from #T where Name=a.Name and ID>a.ID)>0

方法6:
delete a from #T a where ID<>(select top 1 ID from #T where Name=a.name order by ID desc)

方法7:
delete a from #T a where ID<any(select ID from #T where Name=a.Name)


select * from #T
/*
ID          Name Memo
----------- ---- ----
3           A    A3
5           B    B2

(2 行受影响)
*/





--3、删除重复记录没有大小关系时,处理重复值


--> --> (Roy)生成測試數據

if not object_id('Tempdb..#T') is null
   
drop table #T
Go
Create table #T([Num] int,[Name] nvarchar(1))
Insert #T
select 1,N'A' union all
select 1,N'A' union all
select 1,N'A' union all
select 2,N'B' union all
select 2,N'B'
Go

方法1:
if object_id('Tempdb..#') is not null
   
drop table #
Select distinct * into # from #T--排除重复记录结果集生成临时表#

truncate table #T--清空表

insert #T select * from #    --把临时表#插入到表#T中

--查看结果
select * from #T

/*
Num         Name
----------- ----
1           A
2           B

(2 行受影响)
*/

--重新执行测试数据后用方法2
方法2:

alter table #T add ID int identity--新增标识列
go
delete a from  #T a where  exists(select 1 from #T where Num=a.Num and Name=a.Name and ID>a.ID)--只保留一条记录
go
alter table #T drop column ID--删除标识列

--查看结果
select * from #T

/*
Num         Name
----------- ----
1           A
2           B

(2 行受影响)

*/

--重新执行测试数据后用方法3
方法3:
declare Roy_Cursor cursor local for
select count(1)-1,Num,Name from #T group by Num,Name having count(1)>1
declare @con int,@Num int,@Name nvarchar(1)
open Roy_Cursor
fetch next from Roy_Cursor into @con,@Num,@Name
while @@Fetch_status=0
begin
   
set rowcount @con;
   
delete #T where Num=@Num and Name=@Name
   
set rowcount 0;
   
fetch next from Roy_Cursor into @con,@Num,@Name
end
close Roy_Cursor
deallocate Roy_Cursor

--查看结果
select * from #T
/*
Num         Name
----------- ----
1           A
2           B

(2 行受影响)
*/

 

 

问题5:有个表如下

id  projectid      username
1      项目1          张三
2      项目1          张四
3      项目2          张三
4      项目3          张三
5      项目3          张四
6      项目4          张三
7      项目5          张四


我想得到最后结果

id      username        参与项目
1          张三          4个项目
2          张四          4个项目


请问这个SQL该怎么写?

 

--建立表变量

DECLARE @TB TABLE([id] INT, [projectid] NVARCHAR(3), [username] NVARCHAR(2))
INSERT @TB
SELECT 1, N'项目1', N'张三' UNION ALL
SELECT 2, N'项目1', N'张四' UNION ALL
SELECT 3, N'项目2', N'张三' UNION ALL
SELECT 4, N'项目3', N'张三' UNION ALL
SELECT 5, N'项目3', N'张四' UNION ALL
SELECT 6, N'项目4', N'张三' UNION ALL
SELECT 7, N'项目5', N'张四'

 

--代码1

select username,cast(count(*) as varchar(5))+'个项目' as 参与项目
from @TB
group by username

 

--代码2

select id=identity(int,1,1), username,参与项目=cast(count(projectid) as varchar(5)) +'个项目' into #temp from @TB group by username
select * from #temp
drop table #temp

 

--代码3

SELECT Min(id) AS id,
    username,
    RTRIM(COUNT(*)) + '个项目' AS 参与项目
FROM @tb
GROUP BY username

 

 

 




 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值