当 CURSOR 对 SELECT 语句中的函数有影响时如何替换它
How to replace CURSOR when it has effect on functions in SELECT statement
请考虑此代码:
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)
)
光标部分:
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
问题是我想删除 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]
您似乎在尝试将数据分组。试试这个查询。但是我不确定第三列,尤其是没有样本数据
INSERT INTO @outTable
select
mt.[Desc], count(*) / count([Id]) over ()
, COUNT(CASE when MyCol2 = '1' AND MyCol3 IS NOT NULL THEN 1 END) / count(*)
from
MyTable td
join MyMinMaxTable mt on td.MyCol1 between mt.[min] and mt.[max]
where
td.[YEAR] = @Year
and td.[Status] = 1
group by mt.[Desc]
另一种方法是使用 CROSS APPLY
。
SELECT MM.[Desc],
CAST(C1.C1Count AS DECIMAL(15, 2)) / CAST(Tot.TotCount AS decimal (15, 2)) AS C1,
CAST(C2.C2Count AS DECIMAL(15, 2)) / CAST(C1.C1Count AS decimal (15, 2)) AS C2,
CAST(C3.C3Count AS DECIMAL(15, 2)) / CAST(C4.C4Count AS decimal (15, 2)) AS C2
FROM @MyMinMaxTable MM
CROSS APPLY (SELECT COUNT(MyCol1) AS C1Count
FROM @MyTable
WHERE ( MyCol1 BETWEEN MM.Min AND MM.Max )) C1
CROSS APPLY (SELECT COUNT(*) C2Count
FROM @MyTable
WHERE MyCol2 = 1
AND MyCol3 IS NOT NULL)C2
CROSS APPLY (SELECT COUNT(*) C3Count
FROM @MyTable
WHERE MyCol1 >= mm.Min
AND MyCol1 <= mm.Max
AND MyCol2 = 1)C3
CROSS APPLY (SELECT COUNT(*) C4Count
FROM @MyTable
WHERE MyCol2 = 1)C4
CROSS APPLY (SELECT COUNT(*) TotCount
FROM @MyTable)Tot
以下是上述查询的输出。
Desc C1 C2 C2
---------- -------------------- --------------------- ---------------------
Child 0.130434782608695652 3.666666666666666666 0.200000000000000000
Teenager 0.086956521739130434 5.500000000000000000 0.133333333333333333
Youth 0.173913043478260869 2.750000000000000000 0.133333333333333333
Middle-aged 0.347826086956521739 1.375000000000000000 0.333333333333333333
Old 0.347826086956521739 1.375000000000000000 0.333333333333333333
这是一个解决方案。我展开了您的查询并重写了它。
如果你添加额外的范围,这个继续工作,并且不需要交叉应用,hard-coded 子查询范围或其他任何东西。
排序对你来说是一种练习:-)
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,
MyCol1 int,
MyCol2 int,
MyCol3 int null
)
Insert into @MyTable
([Year], MyCol1, 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)
SELECT
MMT.[Desc]
--Ratio of (Age Bracket Matches) / (ALL Rows)
, CAST(COUNT(1) / (SELECT CAST(COUNT(1) AS DECIMAL(15,2)) AS TotalRows FROM @MyTable) AS DECIMAL(15,2)) AS C1
--Ratio of (Rows WHERE MyCol2 = 1 and MyCol3 = NULL) / (Age Bracket Matches)
, CAST((SELECT COUNT(1) FROM @MyTable WHERE MyCol2 = 1 AND MyCol3 IS NOT NULL) / CAST(COUNT(1) AS DECIMAL(15,2)) AS DECIMAL(15,2)) AS C2
--Ratio of (Age Bracket Matches WHERE MyCol2 = 1) / (Rows WHERE WHERE MyCol2 = 1)
, CAST(SUM(CASE WHEN T.MyCol2 = 1 THEN 1 ELSE 0 END) / (SELECT CAST(COUNT(1) AS DECIMAL(15,2)) FROM @MyTable WHERE MyCol2 = 1) AS DECIMAL(15,2)) AS C3
FROM
@MyMinMaxTable AS MMT
INNER JOIN @MyTable AS T ON
T.MyCol1 BETWEEN MMT.[Min] AND MMT.[Max]
GROUP BY
MMT.[Desc]
我认为在这种情况下可以预先计算"The count all records in @MyTable"、“@MyTable 中MyCol2 = 1 且MyCol3 不为空的记录数”和“@MyTable 中MyCol2 的记录数” = 1” 并将它们存储到变量中。
这将使脚本更具可读性和更容易理解。
在这里。希望这有帮助。
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)
)
-- ANSWER BEGIN HERE
-- The count all record in @MyTable
DECLARE @CountAll DECIMAL(5,2)
SET @CountAll = (SELECT COUNT(1) FROM @MyTable)
-- The count record in @MyTable where MyCol2 = 1 and MyCol3 is not null
DECLARE @CountMyCol2Eq1AndMyCol3NotNull DECIMAL(5,2)
SET @CountMyCol2Eq1AndMyCol3NotNull = (SELECT COUNT(1) FROM @MyTable WHERE MyCol2 = 1 AND MyCol3 IS NOT NULL)
-- The count record in @MyTable where MyCol2 = 1
DECLARE @CountMyCol2Eq1 DECIMAL(5,2)
SET @CountMyCol2Eq1 = (SELECT COUNT(1) FROM @MyTable WHERE MyCol2 = 1)
INSERT INTO @Result
SELECT mm.[Desc],
COUNT(1) / @CountAll,
@CountMyCol2Eq1AndMyCol3NotNull / COUNT(1),
SUM(CASE WHEN tt.MyCol2 = 1 THEN 1 ELSE 0 END) / @CountMyCol2Eq1
FROM @MyMinMAxTable mm
JOIN @MyTable tt
ON mm.[Min] <= tt.Age
AND mm.[Max] >= tt.Age
GROUP BY mm.[Desc]
SELECT * FROM @Result
请考虑此代码:
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)
)
光标部分:
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
问题是我想删除 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]
您似乎在尝试将数据分组。试试这个查询。但是我不确定第三列,尤其是没有样本数据
INSERT INTO @outTable
select
mt.[Desc], count(*) / count([Id]) over ()
, COUNT(CASE when MyCol2 = '1' AND MyCol3 IS NOT NULL THEN 1 END) / count(*)
from
MyTable td
join MyMinMaxTable mt on td.MyCol1 between mt.[min] and mt.[max]
where
td.[YEAR] = @Year
and td.[Status] = 1
group by mt.[Desc]
另一种方法是使用 CROSS APPLY
。
SELECT MM.[Desc],
CAST(C1.C1Count AS DECIMAL(15, 2)) / CAST(Tot.TotCount AS decimal (15, 2)) AS C1,
CAST(C2.C2Count AS DECIMAL(15, 2)) / CAST(C1.C1Count AS decimal (15, 2)) AS C2,
CAST(C3.C3Count AS DECIMAL(15, 2)) / CAST(C4.C4Count AS decimal (15, 2)) AS C2
FROM @MyMinMaxTable MM
CROSS APPLY (SELECT COUNT(MyCol1) AS C1Count
FROM @MyTable
WHERE ( MyCol1 BETWEEN MM.Min AND MM.Max )) C1
CROSS APPLY (SELECT COUNT(*) C2Count
FROM @MyTable
WHERE MyCol2 = 1
AND MyCol3 IS NOT NULL)C2
CROSS APPLY (SELECT COUNT(*) C3Count
FROM @MyTable
WHERE MyCol1 >= mm.Min
AND MyCol1 <= mm.Max
AND MyCol2 = 1)C3
CROSS APPLY (SELECT COUNT(*) C4Count
FROM @MyTable
WHERE MyCol2 = 1)C4
CROSS APPLY (SELECT COUNT(*) TotCount
FROM @MyTable)Tot
以下是上述查询的输出。
Desc C1 C2 C2
---------- -------------------- --------------------- ---------------------
Child 0.130434782608695652 3.666666666666666666 0.200000000000000000
Teenager 0.086956521739130434 5.500000000000000000 0.133333333333333333
Youth 0.173913043478260869 2.750000000000000000 0.133333333333333333
Middle-aged 0.347826086956521739 1.375000000000000000 0.333333333333333333
Old 0.347826086956521739 1.375000000000000000 0.333333333333333333
这是一个解决方案。我展开了您的查询并重写了它。 如果你添加额外的范围,这个继续工作,并且不需要交叉应用,hard-coded 子查询范围或其他任何东西。
排序对你来说是一种练习:-)
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,
MyCol1 int,
MyCol2 int,
MyCol3 int null
)
Insert into @MyTable
([Year], MyCol1, 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)
SELECT
MMT.[Desc]
--Ratio of (Age Bracket Matches) / (ALL Rows)
, CAST(COUNT(1) / (SELECT CAST(COUNT(1) AS DECIMAL(15,2)) AS TotalRows FROM @MyTable) AS DECIMAL(15,2)) AS C1
--Ratio of (Rows WHERE MyCol2 = 1 and MyCol3 = NULL) / (Age Bracket Matches)
, CAST((SELECT COUNT(1) FROM @MyTable WHERE MyCol2 = 1 AND MyCol3 IS NOT NULL) / CAST(COUNT(1) AS DECIMAL(15,2)) AS DECIMAL(15,2)) AS C2
--Ratio of (Age Bracket Matches WHERE MyCol2 = 1) / (Rows WHERE WHERE MyCol2 = 1)
, CAST(SUM(CASE WHEN T.MyCol2 = 1 THEN 1 ELSE 0 END) / (SELECT CAST(COUNT(1) AS DECIMAL(15,2)) FROM @MyTable WHERE MyCol2 = 1) AS DECIMAL(15,2)) AS C3
FROM
@MyMinMaxTable AS MMT
INNER JOIN @MyTable AS T ON
T.MyCol1 BETWEEN MMT.[Min] AND MMT.[Max]
GROUP BY
MMT.[Desc]
我认为在这种情况下可以预先计算"The count all records in @MyTable"、“@MyTable 中MyCol2 = 1 且MyCol3 不为空的记录数”和“@MyTable 中MyCol2 的记录数” = 1” 并将它们存储到变量中。
这将使脚本更具可读性和更容易理解。
在这里。希望这有帮助。
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)
)
-- ANSWER BEGIN HERE
-- The count all record in @MyTable
DECLARE @CountAll DECIMAL(5,2)
SET @CountAll = (SELECT COUNT(1) FROM @MyTable)
-- The count record in @MyTable where MyCol2 = 1 and MyCol3 is not null
DECLARE @CountMyCol2Eq1AndMyCol3NotNull DECIMAL(5,2)
SET @CountMyCol2Eq1AndMyCol3NotNull = (SELECT COUNT(1) FROM @MyTable WHERE MyCol2 = 1 AND MyCol3 IS NOT NULL)
-- The count record in @MyTable where MyCol2 = 1
DECLARE @CountMyCol2Eq1 DECIMAL(5,2)
SET @CountMyCol2Eq1 = (SELECT COUNT(1) FROM @MyTable WHERE MyCol2 = 1)
INSERT INTO @Result
SELECT mm.[Desc],
COUNT(1) / @CountAll,
@CountMyCol2Eq1AndMyCol3NotNull / COUNT(1),
SUM(CASE WHEN tt.MyCol2 = 1 THEN 1 ELSE 0 END) / @CountMyCol2Eq1
FROM @MyMinMAxTable mm
JOIN @MyTable tt
ON mm.[Min] <= tt.Age
AND mm.[Max] >= tt.Age
GROUP BY mm.[Desc]
SELECT * FROM @Result