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)实现递归查询
来源:https://www.cnblogs.com/AnchorRon/archive/2012/09/11/2680558.html