Ari*_*ian -3 sql sql-server cursor sql-server-2014
请考虑以下代码:
Declare @MyMinMaxTable Table
(
[Min] int,
[Max] int,
[Desc] NVARCHAR(50)
)
Insert into @MyMinMaxTable
values (0,12,N'Child'),
(13,19,N'Teenager'),
(20,25,N'Youth'),
(25,40,N'Middle-aged'),
(40,99,N'Old')
Declare @MyTable Table
(
Id int identity(1,1),
[Year] int,
Age int,
MyCol2 int,
MyCol3 int null
)
Insert into @MyTable
([Year], Age, MyCol2, MyCol3)
values
(2012, 10, 1 , 1),
(2012, 28, 2 , 3),
(2012, 14, 1 , 7),
(2012, 24, 3 , 3),
(2012, 80, 1 , 6),
(2012, 39, 1 , 3),
(2012, 45, 1 , 5),
(2012, 23, 2 , 6),
(2012, 72, 3 , 8),
(2012, 17, 1 , null),
(2012, 62, 4 , 9),
(2012, 20, 1 , null),
(2012, 5, 1 , 9),
(2012, 8, 1 , 9),
(2012, 25, 1 , null),
(2012, 41, 2 , 2),
(2012, 26, 1 , 2),
(2012, 33, 4 , 2),
(2012, 40, 1 , 2),
(2012, 33, 2 , 3),
(2012, 41, 1 , 5),
(2012, 53, 1 , null),
(2012, 37, 1 , 3)
Declare @Result Table
(
C0 NVARCHAR(50),
c1 decimal(5,2),
C2 decimal(5,2),
C3 decimal(5,2)
)
Run Code Online (Sandbox Code Playgroud)
CURSOR部分:
DECLARE @Min int;
DECLARE @Max int;
DECLARE @Desc nvarchar(50);
DECLARE mycur CURSOR
FOR
SELECT [min],
[max],
[Desc]
FROM @MyMinMaxTable
OPEN mycur
FETCH NEXT FROM mycur INTO @Min, @Max, @Desc
WHILE (@@fetch_status = 0)
BEGIN
INSERT INTO @Result
SELECT @Desc As c0,
(Cast(COUNT(CASE when Age >= @Min AND Age <= @Max THEN 1 END) as decimal(5,2)) / cast(COUNT(Id) as decimal(5,2))) As c1,
(Cast(COUNT(CASE when MyCol2 = 1 AND MyCol3 IS NOT NULL THEN 1 END) as decimal(5,2)) / cast(COUNT(CASE when Age >= @Min AND Age <= @Max THEN 1 END) as decimal(5,2))) As c2,
(Cast(COUNT(CASE when Age >= @Min AND Age <= @Max ANd MyCol2 = 1 THEN 1 END) as decimal(5,2)) / cast(COUNT(CASE when MyCol2 = 1 THEN 1 END) as decimal(5,2))) As c3
FROM @MyTable AS td
FETCH NEXT FROM mycur INTO @Min, @Max, @Desc
END
CLOSE mycur
DEALLOCATE mycur
SELECT * FROM @Result
Run Code Online (Sandbox Code Playgroud)
问题是我想删除CURSOR并编写没有它的查询.在这种情况下它怎么可能?
尝试一下CROSS JOIN并过滤where子句或条件CASE语句.目前还不清楚你的最终目标是什么,所以下面的总量必须调整,但这可能是一个好的开始:
SELECT
mm.[Desc],
(CAST(SUM(CASE WHEN MyCol1 >= mm.Min AND MyCol1 <= mm.Max THEN 1 ELSE 0 END) AS DECIMAL(5,2)) / CAST(COUNT(Id) AS DECIMAL(5,2))) AS C1,
(CAST(SUM(CASE WHEN MyCol2 = 1 AND MyCol3 IS NOT NULL THEN 1 END) AS DECIMAL(5,2)) / CAST(SUM(CASE WHEN MyCol1 >= mm.Min AND MyCol1 <= mm.Max THEN 1 ELSE 0 END) AS DECIMAL(5,2))) AS C2,
(CAST(SUM(CASE WHEN MyCol1 >= mm.Min AND MyCol1 <= mm.Max AND MyCol2 = 1 THEN 1 ELSE 0 END) AS DECIMAL(5,2)) / CAST(SUM(CASE WHEN MyCol2 = 1 THEN 1 ELSE 0 END) AS DECIMAL(5,2))) AS C3
FROM MyTable td
CROSS JOIN MyMinMaxTable mm
GROUP BY mm.[Desc]
Run Code Online (Sandbox Code Playgroud)