SQL技巧

--递归查询的用法总结
--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


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值