SQL的一些经典算法

纵然是瞬间 提交于 2020-02-24 07:20:59

1 SQL分页查询,每页10个数据,取第三页

A) 如果有id列

select top(10)  * from Spider_Hotel

where Spider_Hotel.HotelId not in

( select top (10*2) Spider_Hotel.HotelId from Spider_Hotel)

 

B) 如果没有id列

select top (10) * from

(select ROW_NUMBER() over (order by Name) as Row,* from Spider_Hotel)

 a

where Row>10*2

C) 如果有id列

select top (10) * from Spider_Hotel

where HotelId >(select max(HotelId)

from (select top (10*2) HotelId from Spider_Hotel order by HotelId) as a

)

 

2,数据库删除重复记录。

a, 如果有id列 a,b,c 重复

Delete  from table  where id not in (select max (id) from table group a,b,c)

 

b,  如果没有id列a,b,c 重复 .用row_number() over 函数,制造个Id列

   With Tab as

     Select  row_number() over (order by a) as Row,a,b,c from table

Delete from Tab

Where  Row not in (selete max(Row) from Tab group a,b,c)

 

3,Count函数。

  SELECT COUNT(*),COUNT(FNumber),COUNT(FName) FROM T_Employee

COUNT(*)统计的是结果集的总条数,而

COUNT(FName)统计的则是除了结果集中FName 不为空值(也就是不等于NULL)的记录的总

条数,如果Fname有为空COUNT(*) 不等于COUNT(FNumber)

 

4,求一公司年龄在20-30,40-60岁这两个年龄段的人数,行列转换

 

select SUM(Young) as Young ,SUM(Old) as Old from (

  select

  Users_age,

  sum(case when Users_age between 1 and 3 then 1 else 0 end) as Young,

  sum(case when Users_age between 4 and 6then 1 else 0 end) as Old

from Users

group by Users_age) as s

 

 

//  显示名字,不显示人数,我感觉数据库语句是一个一个判断下去的

select

  years,

  case when age between 20 and 30 then name else '---' end as [20-30],

  case when age between 30 and 40 then name else '---' end as [30-40],

  case when age between 40 and 50 then name else '---' end as [40-50]

from info

group by years,name,age

 

5,连续三天的记录   (查询连续三天抽取同一家酒店同一入住时间的免费房的人员记录)

 

select Member_Code from

dbo.Member a where

exists

(

   select * from Member b

   where b.Register_Date = DATEADD(D,1,a.Register_Date) and a.Member_Code=b.Member_Code

)

and

exists

(

   select * from Member b

   where b.Register_Date = DATEADD(D,2,a.Register_Date) and a.Member_Code=b.Member_Code

)

group by Member_Code

 

 

6,查询表结构   (查询一个数据库所有的数据库表 字段类型 字段大小)

 

--查询表结构

select Dense_Rank() over (order by o.name) as table_order, ROW_NUMBER() over (partition by o.id order by o.name) as column_order,

o.name as table_name, c.name as column_name, t.name+'['+ convert(varchar, c.[length])+']' as column_type

from sysobjects o inner join syscolumns c

inner join systypes t on c.xusertype=t.xusertype

on o.id=c.id

where o.xtype='U'

order by o.name

 

--查询数据库表

select * from dbo.sysobjects

where sysobjects.xtype ='U'

--查询数据库列

select * from syscolumns

where id=21575115

 

7,截止今天的销售额  (一个超市每天都有营业额。列出每天的营业额和截止到每天的总营业额。)

(比如,第一天 营业额 10 总营业额 10,第二天 营业额20 总营业额 30;第二天 营业额 10 总营业额 40)

 

select dates,(select SUM(moneys) from Table as TT

where TT.dates <= T.dates)  from Table as T

 

8,全局临时表,防止用户两地登录。

 

--全局临时表防止用户地登录,但是如果用户量大,这很可能消耗大量资源。

--用户登录,就根据用户Id创建个临时表,如果用户账户异地登录,就会发现

--这张临时表已经存在,返回,提示登录不成功。用户退出系统后,临时表自动消失。

alter proc gp_findtemptable

@v_userid varchar(6),@i_out int output

as

declare @v_sql varchar(100)

if object_id('tempdb.dbo.##'+@v_userid) is null

begin

set @v_sql = 'create table ##'+@v_userid+'(userid varchar(6))'

exec (@v_sql)

set @i_out = 0

end

else

set @i_out = 1

 

 

declare @I int

exec gp_findtemptable 'T00001',@I output

select @I

 

9,查找指定节点的所有子节点的子节点。

create table os(id int,parentid int,desn varchar(10))

--自己不能是自己的节点,否则进入死循环。

 

alter function f_cid(@id int)

returns varchar(500)

as

begin

  declare @t table(id int,desn varchar(10),parentid int,lev int)

  declare @lev int

  set @lev=1

  insert into @t select *,@lev from os where id=@id

  while(@@rowcount>0)

  begin

  set @lev=@lev+1

  insert into @t select a.*,@lev from os a,@t b

  where a.parentid=b.id and b.lev=@lev-1

  end

  declare @cids varchar(500)

  select @cids=isnull(@cids+',','')+ltrim(id) from @t order by lev

  return @cids

end

go

 

执行查询

select *,ids=dbo.f_cid(id) from os

 

 

10, 排名开窗函数 利用ROW_NUMBER() over(partition by 列名order by 列名)进行分组后排序。

 

--统计每一个客户最近下的订单是第几次下的订单。

with tabs as

 (

 select ROW_NUMBER() over(partition by customerID  order by totalPrice) as rows,customerID,totalPrice, DID from OP_Order

 )

 

 select MAX(rows) as '下单次数',customerID from tabs group by customerID

 

--统计分组后的前2名。

with tab as

(

select Id,desn,parentid,ROW_NUMBER() over(partition by desn order by parentid) as rowss    from dbo.os

group by Id,desn,parentid

)

select * from tab where rowss>=2

 

--统计筛选出客户第一次下的订单。。

 with tabs as

 (

 select ROW_NUMBER() over(partition by customerID  order by insDT) as rows,* from OP_Order

 )

 select * from tabs where rows = 1

11, 聚合开窗函数 使用over子句与rows_number()以及聚合函数进行使用,可以进行编号以及各种操作。而且利用over子句的分组效率比group by子句的效率更高。

 

--在订单表(order)中统计中,生成这么每一条记录都包含如下信息:“所有订单的总和(AllTotalPrice)”、“每一位客户的所有订单的总(cusTotalPrice)”、”每一单的金额(totalPrice)“,”每一个客户订单的平均金额(avgCusprice)“,”所有客户的所有订单的平均金额(avgTotalPrice)“,"订单金额最小值(MinTotalPrice)","客户订单金额最小值(MinCusPrice)","订单金额最大值(MaxTotalPrice)","客户订单金额最大值(MaxCusPrice)","客户所购的总额在所有的订单中总额的比例(CusAllPercent)","每一订单的金额在每一位客户总额中所占的比例(cusToPercent)"。

with tabs as

  (

   select

  customerID,

  SUM(totalPrice) over() as AllTotalPrice,

  SUM(totalPrice) over(partition by customerID) as cusTotalPrice,

  AVG(totalPrice) over(partition by customerID) as avgCusprice,

  AVG(totalPrice) over() as avgTotalPrice,

  MIN(totalPrice) over() as MinTotalPrice,

  MIN(totalPrice) over(partition by customerID) as MinCusPrice,

  MAX(totalPrice) over() as MaxTotalPrice,

  MAX(totalPrice) over(partition by customerID) as MaxCusPrice,

  totalPrice

  from OP_Order

  )

  select

  customerID,

  AllTotalPrice,

  cusTotalPrice,

  totalPrice,

  avgCusprice,

  avgTotalPrice,

  MinTotalPrice,

  MinCusPrice,

  MaxTotalPrice,

  MaxCusPrice,

  cusTotalPrice/AllTotalPrice as CusAllPercent,

  totalPrice/cusTotalPrice as cusToPercent

  from tabs

12 通用表达式:CTE(Common Table Expression)实现递归查询

With AA as

(

select Id,SupplierName, ParentId,0 as levels from Supplier where ParentId='0'

union all select BB.Id,BB.SupplierName, BB.ParentId,R.levels+1 as levels from Supplier as BB

join AA as R

on BB.ParentId=R.Id

)

select * from AA

--通用表达式:CTE(Common Table Expression)实现递归查询

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!