sqlserver分类排序,将父子节点的放在一起
Sqlserver父子节点查询与分类排序
已知题目:
表测试数据如下:
create table C(Id int ,Name varchar(20),Parent_id int)
insert into C values(1,'w',null)
insert into C values(3,'d',null)
insert into C values(5,'d',1)
insert into C values(6,'f',3)
insert into C values(7,'f',1)
insert into C values(8,'g',null)
insert into C values(9,'g',null)
insert into C values(10,'gd',6)
insert into C values(13,'gx',7)
方法一:
--网络上某人的方法
select * from
(select ID,Name,Parent_id,(case when id>Parent_id then Parent_id else id end) flag from C) t order by flag,id
方法二:
思路:将所有根节点提出然后获得根节点下的所有子节点,遍历根节点的记录。
使用union all 连接即可:
·首先创建函数GetSubNode_C(@parentid int):
create function GetSubNode_C(@parentid int)
returns @t table(Id int ,Name varchar(20),Parent_id int,Level int)
As
Begin
declare @Level int --等级根节点等级为1
set @Level=1
insert into @t select Id,Name,Parent_id,@Level from C where Id=@parentid
while @@rowcount>0 --如果至少有一条子节点
begin
set @Level=@Level+1
insert into @t select a.Id,,a.Parent_id,@Level from C a,@t b
where a.Parent_id in (select Id from C where Id=b.ID)
and b.Level=@Level-1
end
return
End
·然后游标遍历所有根节点(parentid is null)的记录,拼装sql语句,最后执行
declare @sql varchar(8000)
set @sql=''
declare @Id int
declare cur cursor for
select id from C where parent_id is null
open cur
fetch next from cur into @Id
while @@fetch_status=0
begin
if len(@sql)=0
set @sql=@sql+'select * from dbo.GetSubNode_C('+cast(@Id as varchar(10))+')'
else
set @sql=@sql+' union all select * from dbo.GetSubNode_C('+cast(@Id as varchar(10))+')' fetch next from cur into @Id
end
close cur
deallocate cur
exec(@sql)
运行结果截图:。
sqlserver order by用法
一、SQL Server Order By 介绍在 SQL Server 中,Order By 语句用于对查询结果进行排序。
它基于一个或多个列的值对结果集进行排序,并且可以指定升序或降序排序顺序。
Order By 语句通常用于 Select 语句的末尾,以便按照特定的顺序返回数据。
在本篇文章中,我们将详细探讨 SQL Server Order By 的用法及注意事项。
二、基本语法Order By 语句的基本语法如下:```sqlSELECT column1, column2, ...FROM table_nameORDER BY column1, column2, ... ASC|DESC;```其中,column1, column2, ... 用于指定需要排序的列,table_name 是需要查询的表名,ASC 和 DESC 分别表示升序和降序排序。
如果不指定排序顺序,默认情况下为升序(ASC)。
三、单列排序如果只需要按照单个列进行排序,可以简单地在 Order By 语句中指定列名和排序顺序,例如:```sqlSELECT *FROM employeesORDER BY last_name ASC;```上述示例中,我们使用 Order By 对 employees 表中的 last_name 列进行升序排序。
四、多列排序除了单列排序之外,Order By 也支持对多个列进行排序。
在指定多个排序列时,SQL Server 首先根据第一个指定的列进行排序,然后再按照第二个列进行排序,以此类推。
示例如下:```sqlSELECT *FROM employeesORDER BY department_id ASC, last_name DESC;```上述示例中,我们首先按照 department_id 进行升序排序,然后在每个部门内再按照 last_name 进行降序排序。
五、注意事项1. Null 值排序:在 SQL Server 中,默认情况下,Null 值会被排在排序结果的末尾。
SqlServer父节点与子节点查询及递归
SqlServer⽗节点与⼦节点查询及递归在最近⽼是⽤到这个SQL,所以记下来了:1:创建表CREATE TABLE [dbo].[BD_Booklet]([ObjID] [int] IDENTITY(1,1) NOT NULL,[ParentID] [int] NULL,[ObjLen] [int] NULL,[ObjName] [nvarchar](50) NULL,[ObjUrl] [nvarchar](200) NULL,[ObjExpress] [nvarchar](500) NULL,[ObjTime] [nvarchar](50) NULL,[ObjUID] [nvarchar](10) NULL,[ObjDemo] [text] NULL,CONSTRAINT [PK_BD_Booklet] PRIMARY KEY CLUSTERED([ObjID] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]GO2:添加数据(⾃⼰添加)3:根据⽗节点查询⼦节点信息(所有⼦节点,包括⼦节点的⼦节点)--公⽤表表达式实现⽗节点查询⼦节点DECLARE @ParentID intSET @ParentID='1'with CTEGetChild as(select * from BD_Booklet where ParentID=@ParentIDUNION ALL(SELECT a.* from BD_Booklet as a inner joinCTEGetChild as b on a.ParentID=b.ObjID))SELECT * FROM CTEGetChild4:根据节点得到最初始的⽗节点(根节点)()--公⽤表表达式实现⼦节点查询⽗节点DECLARE @ChildID intSET @ChildID=6DECLARE @CETParentID intselect @CETParentID=ParentID FROM BD_Booklet where ObjID=@ChildIDwith CTEGetParent as(select * from BD_Booklet where ObjID=@CETParentIDUNION ALL(SELECT a.* from BD_Booklet as a inner joinCTEGetParent as b on a.ObjID=b.ParentID)) SELECT * FROM CTEGetParent说明|:近期发现该⽅法只能查询出三级,对于4级和5级的没有办法。
SQLServer序列(SEQUENCE)使用
SQLServer序列(SEQUENCE)使⽤众所周知,在之前的SQL SERVER版本中,⼀般采⽤GUID或者IDENTITY来作为标⽰符,但是IDENTITY是⼀个表对象,只能保证在⼀张表⾥⾯的序列,当我们遇到以下情况时,如上表,我们需要在多表之间,实现ID的⼀致性,在SQL SERVER⾥⾯就会有⼀定的⿇烦,通常我们会使⽤额外使⽤⼀张TEMP表来映射这些ID的关系然后再从中取序列来完成。
SEQUENCE在ORACLE中其实很早就存在了,SQL SERVER 2012的SEQUENCE功能和那个相似,是⼀个基于SCHEMA的对象,所以可以被多表调⽤。
序列是⽤户定义的绑定到架构的对象,该对象可根据创建序列所依据的规范来⽣成数值序列。
这组数值以定义的间隔按升序或降序⽣成,并且可配置为⽤尽时重新启动(循环)。
序列不与特定表相关联,这⼀点与标识列不同。
应⽤程序将引⽤某⼀序列对象以便检索其下⼀个值。
序列与表之间的关系由应⽤程序控制。
⽤户应⽤程序可以引⽤⼀个序列对象,并跨多个⾏和表协调值。
与在插⼊⾏时⽣成的标识列值不同,应⽤程序可以获得下⼀个序列号,⽽不必通过调⽤ NEXT VALUE FOR 函数来插⼊⾏。
使⽤sp_sequence_get_range同时获取多个序列号。
SEQUENCE语法如下:(创建⼀个序列对象并指定其属性)CREATE SEQUENCE [schema_name . ] sequence_name[ AS [ built_in_integer_type | user-defined_integer_type ] ][ START WITH <constant> ][ INCREMENT BY <constant> ][ { MINVALUE [ <constant> ] } | { NO MINVALUE } ][ { MAXVALUE [ <constant> ] } | { NO MAXVALUE } ][ CYCLE | { NO CYCLE } ][ { CACHE [ <constant> ] } | { NO CACHE } ][ ; ]sequence_name 指定数据库中标识序列的唯⼀名称。
Sqlserver使用CTE如何按子查询排序?
Sqlserver使⽤CTE如何按⼦查询排序?需求:查出最近有更改的客户信息(按最后更改时间排序,来⾃SystemLog表LogDateTime字段)说明:Customer:客户信息表SystemLog:系统⽇志表,记录所有表信息的增,删,改⾃⼰公司开发的⾏业软件,不仅⾃⼰公司有在⽤,其他公司也在⽤,本公司进⾏软件维护和提供升级服务由于之前的设计客户信息表并没有更改时间字段,⽽现在该系统已经在N个不同的数据库⾥运⾏导致不能随意更改数据库结构(虽然可以升级,但代价太⼤)不能使⽤视图及存储过程只能使⽤Sql语句我写的Sql及效果,虽然可以实现效果,但Sqlsrever的执⾏计划和IO情况很糟糕(个⼈理解SystemLog查询了再次)--客户信息按照最后更改时间排序:WITH _temp AS(SELECTCustomerId,CompanyName,(SELECT TOP 1 LogDateTime FROM SystemLog WHERE LogType='更改' AND LogTable='Customer' AND Rid=CustomerId ORDER BY ID DESC )AS ed,ROW_NUMBER() OVER ( ORDER BY (SELECT TOP 1 LogDateTime FROM SystemLog WHERE LogType='更改'AND LogTable='Customer' AND Rid=CustomerId ORDER BY ID DESC ) DESC ) as RowNumber FROM CustomerWHERE CustomerStatus=18)SELECT * FROM _temp WHERE RowNumber BETWEEN 0 AND 10 ORDER BY ed DESC查询客户信息的系统⽇志SELECT TOP10 s.Rid AS CustomerId, CompanyName , s.LogDateTimeFROM SystemLog sLEFT JOIN Customer c ON s.Rid=CustomerIdWHERE LogType='更改'AND LogTable='Customer'AND c.CustomerStatus=18ORDER BY s.id DESCset statistics io on;(10 ⾏受影响)表 'SystemLog'。
sqlserver 中group by 字符串拼接
标题:SQL Server中使用GROUP BY进行字符串拼接的方法一、介绍在SQL Server中,我们经常会遇到需要对数据进行分组并进行字符串拼接的情况。
比如我们需要将某个字段按照相同的某个字段进行分组,并将这个字段的数据进行拼接。
这个时候,我们就需要使用GROUP BY进行字符串拼接了。
二、使用STUFF和FOR XML PATH方法进行字符串拼接在SQL Server中,我们可以使用STUFF和FOR XML PATH方法来进行字符串的拼接。
具体步骤如下:1. 在SELECT语句中使用STUFF和FOR XML PATH方法进行字符串拼接```sqlSELECT column1,STUFF((SELECT ', ' + column2FROM table1 t2WHERE t1.column1 = t2.column1FOR XML PATH('')), 1, 2, '') AS concatenated_column2FROM table1 t1GROUP BY column1;```在这个例子中,我们首先在SELECT语句中使用STUFF和FOR XML PATH方法来对column2进行字符串拼接。
然后使用GROUP BY对column1进行分组。
2. 解释- `STUFF`函数用来替换字符串的子字符串。
它的语法是`STUFF(string_expression, start, length, replacement_characters)`。
在这个例子中,我们将`start`设为1,`length`设为2,`replacement_characters`设为空字符串,表示替换从字符串的第一个字符开始的两个字符为一个空字符串。
- `FOR XML PATH('')`表示将查询结果转换为XML,并且将每一行的数据合并为一个字符串。
sql server组织树 语法
sql server组织树语法SQL Server组织树语法在SQL Server数据库管理系统中,组织树(也称为层次结构)是一种常见的数据结构,用于表示具有层次关系的数据。
组织树通常用于组织机构、产品分类等场景,其中每个节点代表一个实体,节点之间通过父子关系进行连接。
组织树可以通过多种方式实现,其中一种常见的方式是使用递归查询和CTE(公共表表达式)来构建树结构。
本文将介绍如何使用SQL Server的语法来组织树结构。
1. 创建表格我们需要创建一个表格来存储组织树的数据。
假设我们要创建一个组织机构的树结构,包含以下字段:- ID:节点的唯一标识符- Name:节点的名称- ParentID:父节点的ID可以使用以下SQL语句创建组织树表格:```sqlCREATE TABLE OrganizationTree (ID INT PRIMARY KEY,Name VARCHAR(100),ParentID INT);```2. 插入数据接下来,我们需要向组织树表格中插入数据。
下面是一个示例插入语句:```sqlINSERT INTO OrganizationTree (ID, Name, ParentID) VALUES (1, '总公司', NULL),(2, '分公司A', 1),(3, '分公司B', 1),(4, '部门A1', 2),(5, '部门A2', 2),(6, '部门B1', 3),(7, '部门B2', 3);```在这个示例中,我们创建了一个包含总公司、两个分公司和四个部门的组织树。
3. 查询组织树现在我们可以使用递归查询和CTE来查询组织树结构。
下面是一个示例查询语句:```sqlWITH RecursiveCTE AS (SELECT ID, Name, ParentID, 0 AS LevelFROM OrganizationTreeWHERE ParentID IS NULLUNION ALLSELECT ot.ID, , ot.ParentID, rc.Level + 1FROM OrganizationTree otINNER JOIN RecursiveCTE rc ON ot.ParentID = rc.ID)SELECT ID, Name, LevelFROM RecursiveCTEORDER BY Level, ID;```在这个示例中,我们使用递归CTE来遍历组织树,并按照层次和节点ID排序结果。
sql中排序的用法 -回复
sql中排序的用法-回复SQL中排序的用法排序是SQL中非常重要的一个功能,它允许我们根据指定的条件对查询结果进行排序。
在实际应用中,排序通常是根据某些列的值来进行的,这些列可以是数字型、字符型或日期型的列。
在本文中,我们将详细介绍SQL 中排序的用法,包括升序排序、降序排序、多列排序以及对空值的排序处理等。
一、升序排序升序排序是最简单的一种排序方式,它按照指定列的值从小到大进行排序。
在SQL语句中,我们可以使用ORDER BY关键字来指定要排序的列,并通过ASC关键字来指定排序方式为升序。
以下是一个示例:SELECT * FROM studentsORDER BY age ASC;上述语句将按照学生表中的age列的值进行升序排序。
二、降序排序降序排序与升序排序正好相反,它按照指定列的值从大到小进行排序。
在SQL语句中,我们可以使用DESC关键字来指定排序方式为降序。
以下是一个示例:SELECT * FROM studentsORDER BY score DESC;上述语句将按照学生表中的score列的值进行降序排序。
需要注意的是,在不指定排序方式的情况下,默认为升序排序。
三、多列排序除了对单个列进行排序之外,我们还可以对多个列进行排序。
当多个列的值存在相同时,会依次按照后面的列值进行排序。
在SQL语句中,我们只需要在ORDER BY子句中指定多个列名即可。
以下是一个示例:SELECT * FROM studentsORDER BY class, score DESC;上述语句将按照学生表中的class列进行升序排序,当class列值相同时,再根据score列进行降序排序。
四、空值排序处理在排序过程中,如果存在空值,需要特殊处理。
在SQL中,空值通常被认为是最小值或最大值,具体取决于升序或降序排序的方式。
为了更精确地控制空值的排序方式,我们可以使用NULLS FIRST或NULLS LAST来指定空值的排序位置。
SQL WITH AS实现父子递归查询
conn.Open();
SqlCommand cmd = new SqlCommand();
mandText = "pr_GetLocations";
mandType = CommandType.StoredProcedure;
cmd.Connection = conn;
[parent] [int]
)
GO
3.2创建测试数据:
INSERT tb_loc(id,name,parent) VALUES( 1,'河北省',NULL)
INSERT tb_loc(id,name,parent) VALUES( 2,'石家庄',1)
INSERT tb_loc(id,name,parent) VALUES( 3,'保定',1)
3.重复第2步直到读取完全部数据
可以看到container集合始终保存了当前层的上层所有的实体对象,并且为了在更换层数后能够正确的更新container集合,使用current集合保存当前层的实体对象。
3.8编写GetLocationFromReader方法,用于从数据阅读器中返回Location实体对象,并将层数信息使用out参数返回:
INSERT tb_loc(id,name,parent) VALUES( 12,'北焦村东',7)
INSERT tb_loc(id,name,parent) VALUES( 13,'北焦村西',7)
INSERT tb_loc(id,name,parent) VALUES( 14,'桥东区',3)
INSERT tb_loc(id,name,parent) VALUES( 15,'桥西区',3)
SQLServer中使用COLLATE关键字,解决排序规则不同的问题
SQLServer中使⽤COLLATE关键字,解决排序规则不同的问题在SQL Server中的字符类型都是有排序规则(collation)的,例如在下⾯的SQL语句中,我们建⽴了⼀个表变量@table_people,其中我们使⽤关键字COLLATE给列[Name]定义了排序规则"Chinese_PRC_CI_AS",也给列[Description]定义了排序规则"SQL_Latin1_General_CP1_CI_AS":DECLARE@table_people TABLE([Name]NVARCHAR(50) COLLATE Chinese_PRC_CI_AS,[Description]NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS,[Age]INT)INSERT INTO@table_people([Name],[Description],[Age])VALUES(N'张三' COLLATE Chinese_PRC_CI_AS,N'这个⼈叫张三' COLLATE SQL_Latin1_General_CP1_CI_AS,31),(N'李四' COLLATE Chinese_PRC_CI_AS,N'这个⼈叫李四' COLLATE SQL_Latin1_General_CP1_CI_AS,32),(N'王五' COLLATE Chinese_PRC_CI_AS,N'这个⼈叫王五' COLLATE SQL_Latin1_General_CP1_CI_AS,33)SELECT*FROM@table_people这段SQL代码可以成功执⾏,因为我们使⽤了COLLATE关键字为每⼀个字符串指定了相应的排序规则。
但是,如果我们对不同排序规则的字符类型进⾏操作的时候就会报错,如下所⽰:DECLARE@table_people TABLE([Name]NVARCHAR(50) COLLATE Chinese_PRC_CI_AS,[Description]NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS,[Age]INT)INSERT INTO@table_people([Name],[Description],[Age])VALUES(N'张三' COLLATE Chinese_PRC_CI_AS,N'这个⼈叫张三' COLLATE SQL_Latin1_General_CP1_CI_AS,31),(N'李四' COLLATE Chinese_PRC_CI_AS,N'这个⼈叫李四' COLLATE SQL_Latin1_General_CP1_CI_AS,32),(N'王五' COLLATE Chinese_PRC_CI_AS,N'王五' COLLATE SQL_Latin1_General_CP1_CI_AS,33)SELECT*FROM@table_people WHERE[Name]=[Description]--Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Chinese_PRC_CI_AS" in the equal to operation.上⾯的SQL语句,会在最后的SELECT语句报错:Msg 468, Level 16, State 9, Line 14Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Chinese_PRC_CI_AS" in the equal to operation.由于我们在SELECT语句的WHERE条件中⽐较了列[Name]和列[Description]的值,但是[Name]和[Description]是两个排序规则不同的列,不能直接进⾏⽐较操作,所以我们要使⽤COLLATE关键字对排序规则进⾏转换后,才能进⾏⽐较:DECLARE@table_people TABLE([Name]NVARCHAR(50) COLLATE Chinese_PRC_CI_AS,[Description]NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS,[Age]INT)INSERT INTO@table_people([Name],[Description],[Age])VALUES(N'张三' COLLATE Chinese_PRC_CI_AS,N'这个⼈叫张三' COLLATE SQL_Latin1_General_CP1_CI_AS,31),(N'李四' COLLATE Chinese_PRC_CI_AS,N'这个⼈叫李四' COLLATE SQL_Latin1_General_CP1_CI_AS,32),(N'王五' COLLATE Chinese_PRC_CI_AS,N'王五' COLLATE SQL_Latin1_General_CP1_CI_AS,33)--将列[Description]的排序规则转换为Chinese_PRC_CI_ASSELECT*FROM@table_people WHERE[Name]=[Description] COLLATE Chinese_PRC_CI_AS--将列[Name]的排序规则转换为SQL_Latin1_General_CP1_CI_ASSELECT*FROM@table_people WHERE[Name] COLLATE SQL_Latin1_General_CP1_CI_AS=[Description]由于现在我们使⽤COLLATE关键字对列[Name]和列[Description]的排序规则进⾏了转换,保证了SELECT语句WHERE条件中等号两边字符类型的排序规则是相同的,所以现在两个SELECT语句都不会报错,并成功返回了查询结果。
整理一下SQLSERVER的排序规则
整理⼀下SQLSERVER的排序规则SQL SERVER的排序规则平时使⽤不是很多,也许不少初学者还⽐较陌⽣,但有⼀个错误⼤家应是经常碰到: SQL SERVER数据库,在跨库多表连接查询时,若两数据库默认字符集不同,系统就会返回这样的错误:“⽆法解决 equal to 操作的排序规则冲突。
”⼀.错误分析: 这个错误是因为排序规则不⼀致造成的,我们做个测试,⽐如:create table #t1(name varchar(20) collate Albanian_CI_AI_WS,value int)create table #t2(name varchar(20) collate Chinese_PRC_CI_AI_WS,value int )表建好后,执⾏连接查询:select * from #t1 A inner join #t2 B on =这样,错误就出现了:服务器: 消息 446,级别 16,状态 9,⾏ 1⽆法解决 equal to 操作的排序规则冲突。
要排除这个错误,最简单⽅法是,表连接时指定它的排序规则,这样错误就不再出现了。
语句这样写:select *from #t1 A inner join #t2 Bon = collate Chinese_PRC_CI_AI_WS⼆.排序规则简介:什么叫排序规则呢?MS是这样描述的:"在 Microsoft SQL Server 2000 中,字符串的物理存储由排序规则控制。
排序规则指定表⽰每个字符的位模式以及存储和⽐较字符所使⽤的规则。
" 在查询分析器内执⾏下⾯语句,可以得到SQL SERVER⽀持的所有排序规则。
select * from ::fn_helpcollations()排序规则名称由两部份构成,前半部份是指本排序规则所⽀持的字符集。
如: Chinese_PRC_CS_AI_WS前半部份:指UNICODE字符集,Chinese_PRC_指针对⼤陆简体字UNICODE的排序规则。
