--递归查询的用法总结
--ROW_NUMBER的用法总结
WITH StepCTE AS
(
SELECT CategoryCode,1 as Lev,CategoryCode AS Leve1_ID,
NULL AS Leve2_ID,NULL AS Leve3_ID,NULL AS Leve4_ID,NULL AS Leve5_ID
FROM ProductCategory WHERE ParentCategoryCode=0 UNION ALL
SELECT T.CategoryCode,CTE.Lev + 1,CTE.Leve1_ID,
CASE WHEN CTE.Lev = 1 THEN T.CategoryCode ELSE CTE.Leve2_ID END AS [Leve2_ID],
CASE WHEN CTE.Lev = 2 THEN T.CategoryCode ELSE CTE.Leve3_ID END AS [Leve3_ID],
CASE WHEN CTE.Lev = 3 THEN T.CategoryCode ELSE CTE.Leve4_ID END AS [Leve4_ID],
CASE WHEN CTE.Lev = 4 THEN T.CategoryCode ELSE CTE.Leve5_ID END AS [Leve5_ID]
FROM dbo.ProductCategory T INNER JOIN StepCTE CTE ON T.ParentCategoryCode = CTE.CategoryCode
)
SELECT * FROM StepCTE;
--和上面的方法一样获取分类的各级分类的ID及名称
WITH StepCTE AS
(
SELECT PCID,ParentID,CategoryName,1 as Lev,PCID AS Level1_ID,
NULL AS Level2_ID,NULL AS Level3_ID,NULL AS Level4_ID,NULL AS Level5_ID
FROM WProductCategorys WHERE ParentID=0 UNION ALL
SELECT T.PCID,T.ParentID,T.CategoryName,CTE.Lev + 1,CTE.Level1_ID,
CASE WHEN CTE.Lev = 1 THEN T.PCID ELSE CTE.Level2_ID END AS [Level2_ID],
CASE WHEN CTE.Lev = 2 THEN T.PCID ELSE CTE.Level3_ID END AS [Level3_ID],
CASE WHEN CTE.Lev = 3 THEN T.PCID ELSE CTE.Level4_ID END AS [Level4_ID],
CASE WHEN CTE.Lev = 4 THEN T.PCID ELSE CTE.Level5_ID END AS [Level5_ID]
FROM dbo.WProductCategorys T INNER JOIN StepCTE CTE ON T.ParentID = CTE.PCID
)
SELECT StepCTE.PCID AS PCID,
topLevel.PCID AS Level1_ID, topLevel.CategoryName as Level1_Name,
secondLevel.PCID AS Level2_ID,secondLevel.CategoryName as Level2_Name,
thirdLevel.PCID AS Level3_ID,thirdLevel.CategoryName as Level3_Name,
fourthLevel.PCID AS Level4_ID,fourthLevel.CategoryName as Level4_Name,
fifthLevel.PCID AS Level5_ID,fifthLevel.CategoryName as Level5_Name
FROM StepCTE JOIN dbo.WProductCategorys topLevel ON (StepCTE.Level1_ID = topLevel.PCID)
LEFT JOIN dbo.WProductCategorys secondLevel ON (StepCTE.Level2_ID = secondLevel.PCID)
LEFT JOIN dbo.WProductCategorys thirdLevel ON (StepCTE.Level3_ID = thirdLevel.PCID)
LEFT JOIN dbo.WProductCategorys fourthLevel ON (StepCTE.Level4_ID = fourthLevel.PCID)
LEFT JOIN dbo.WProductCategorys fifthLevel ON (StepCTE.Level5_ID = fifthLevel.PCID)
--ROW_NUMBER和递归方法联合使用的实例
WITH CateCTE AS
(
--根据父类和子类的关系将所有的类别按照级别用->连接
SELECT nc.CategoryCode,nc.ParentCategoryCode,CAST(nc.CategoryName AS NVARCHAR(300)) AS CategoryName
FROM ProductCategory nc
WHERE nc.ParentCategoryCode=0
UNION ALL
SELECT nc1.CategoryCode,nc1.ParentCategoryCode,
CAST(cte.CategoryName +'->'+ nc1.CategoryName AS NVARCHAR(300)) AS CategoryName
FROM ProductCategory nc1
INNER JOIN CateCTE cte ON cte.CategoryCode=nc1.ParentCategoryCode
),
--将一对多的数据变为一对一的多行合并的SQL
AdType AS
(
--ROW_NUMBER的用法,一个SrcId对应多个CategoryCode(TypeId)针对每一个SrcId对应的TypeId进行编号
SELECT DISTINCT oat.SrcId,c.CategoryName,
ROW_NUMBER() OVER(PARTITION BY oat.srcid ORDER BY c.CategoryCode) AS Num
FROM LAdType oat
INNER JOIN CateCTE c ON c.CategoryCode=oat.TypeId
INNER JOIN LAdSrc oas ON oas.Id=oat.SrcId
),
TypeCTE AS
(
--利用递归将行合并用“,”分割
SELECT a1.SrcId,CAST(a1.CategoryName AS NVARCHAR(1000)) AS CategoryNames,a1.Num
FROM AdType AS a1
WHERE a1.Num=1
UNION ALL
SELECT a2.SrcId,CAST(t.CategoryNames +','+ a2.CategoryName AS NVARCHAR(1000)),a2.Num
FROM AdType AS a2
INNER JOIN TypeCTE AS t ON a2.SrcId=t.SrcId and a2.Num=t.Num+1
)
SELECT oas.Id,oas.[FileName],oas.Name,oas.TypeCount,oas.ValidBeginDate,oas.ValidEndDate,AdType.TypeNames
FROM LAdSrc oas
INNER JOIN
(
SELECT t.SrcId,MAX(t.CategoryNames) AS TypeNames FROM TypeCTE AS t GROUP BY t.SrcId --取合并后最长的一行
)
AdType ON oas.Id=AdType.SrcId
--//--
--在SQL语句中判断输入的参数是否为空等判断,不需要在C#代码中用If……else判断来拼接字符串
DECLARE @cateId INT;
SET @cateId=0;
--如果@cateId为0则查询全部,否则只查询CategoryCode=@cateId的分类
SELECT * FROM ProductCategory
WHERE 1=1
AND 1=(CASE WHEN @cateId=0 THEN 1 WHEN CategoryCode=@cateId THEN 1 END)
--行转换列相关的方法
WITH Test AS
(
SELECT '张三' AS [姓名],'语文' AS [科目], 72 AS [分数],'2012' AS [年份]
UNION ALL
SELECT '李四' AS [姓名],'语文' AS [科目], 80 AS [分数],'2012' AS [年份]
UNION ALL
SELECT '王五' AS [姓名],'语文' AS [科目], 63 AS [分数],'2012' AS [年份]
UNION ALL
SELECT '张三' AS [姓名],'语文' AS [科目], 60 AS [分数],'2011' AS [年份]
UNION ALL
SELECT '李四' AS [姓名],'语文' AS [科目], 92 AS [分数],'2011' AS [年份]
UNION ALL
SELECT '王五' AS [姓名],'语文' AS [科目], 74 AS [分数],'2011' AS [年份]
UNION ALL
SELECT '张三' AS [姓名],'数学' AS [科目], 68 AS [分数],'2012' AS [年份]
UNION ALL
SELECT '李四' AS [姓名],'数学' AS [科目], 90 AS [分数],'2012' AS [年份]
UNION ALL
SELECT '王五' AS [姓名],'数学' AS [科目], 70 AS [分数],'2012' AS [年份]
UNION ALL
SELECT '张三' AS [姓名],'数学' AS [科目], 60 AS [分数],'2011' AS [年份]
UNION ALL
SELECT '李四' AS [姓名],'数学' AS [科目], 97 AS [分数],'2011' AS [年份]
UNION ALL
SELECT '王五' AS [姓名],'数学' AS [科目], 77 AS [分数],'2011' AS [年份]
UNION ALL
SELECT '张三' AS [姓名],'英语' AS [科目], 58 AS [分数],'2012' AS [年份]
UNION ALL
SELECT '李四' AS [姓名],'英语' AS [科目], 73 AS [分数],'2012' AS [年份]
UNION ALL
SELECT '王五' AS [姓名],'英语' AS [科目], 88 AS [分数],'2012' AS [年份]
UNION ALL
SELECT '张三' AS [姓名],'英语' AS [科目], 89 AS [分数],'2011' AS [年份]
UNION ALL
SELECT '李四' AS [姓名],'英语' AS [科目], 63 AS [分数],'2011' AS [年份]
UNION ALL
SELECT '王五' AS [姓名],'英语' AS [科目], 68 AS [分数],'2011' AS [年份]
)
--1、用Case when语句
SELECT [姓名],[年份],SUM([英语]) AS [英语],SUM(语文) AS [语文],SUM([数学]) AS [数学]
FROM
(
SELECT [姓名],[年份],
(CASE [科目] WHEN '英语' THEN [分数] ELSE 0 END) AS [英语],
(CASE [科目] WHEN '语文' THEN [分数] ELSE 0 END) AS [语文],
(CASE [科目] WHEN '数学' THEN [分数] ELSE 0 END) AS [数学]
FROM Test
) a
GROUP BY [姓名],[年份]
--在SQL2005+中可以这样写
SELECT * FROM Test PIVOT(SUM([分数]) FOR [科目] IN (语文,数学,英语)) AS P