我有一个像@tbl一样的表,我需要写一个查询,好像有3个以上的记录可用 对于特定的cid,特定cid的avg(特定cid的val)应该针对每个id显示,如果小于 3个记录可用于特定的cid然后avg(所有记录的val可用)。
请建议。
declare @tbl table(id int, cid int, val float )
insert into @tbl
values(1,100,20),(2,100,30),(3,100,25),(4,100,31),(5,100,50),
(6,200,30),(7,200,30),(8,300,90)
答案 0 :(得分:2)
您的描述不明确,但我相信您需要加窗功能:
WITH cte AS (
SELECT *, COUNT(*) OVER(PARTITION BY cid) AS cnt
FROM @tbl
)
SELECT id, (SELECT AVG(val) FROM cte) AS Av
FROM cte
WHERE cnt <=3
UNION ALL
SELECT id, AVG(val) OVER(PARTITION BY cid) AS Av
FROM cte
WHERE cnt > 3
ORDER BY id;
<强> DBFiddle Demo 强>
修改强>
SELECT id,
CASE WHEN COUNT(*) OVER(PARTITION BY cid) <= 3 THEN AVG(val) OVER()
ELSE AVG(val) OVER(PARTITION BY cid)
END
FROM @tbl
ORDER BY id;
<强> DBFiddle Demo2 强>
答案 1 :(得分:0)
您可以尝试以下操作。首先计算每个Cid
的平均值,具体取决于它的出现次数,然后将每个Id
加入;WITH CidAverages AS
(
SELECT
T.cid,
Average = CASE
WHEN COUNT(1) >= 3 THEN AVG(T.val)
ELSE (SELECT AVG(Val) FROM @tbl) END
FROM
@tbl AS T
GROUP BY
T.cid
)
SELECT
T.*,
C.Average
FROM
@tbl AS T
INNER JOIN CidAverages AS C ON T.cid = C.cid
以显示所有表格。
textContent
答案 2 :(得分:0)
鉴于评论中的澄清,我认为这是意图
declare @tbl table(id int, cid int, val float )
insert into @tbl
values(1,100,20),(2,100,30),(3,100,25),(4,100,31),(5,100,50),
(6,200,30),(7,200,30),(8,300,90);
select distinct
cid
, case
when count(*) over (partition by cid) > 3 then avg(val) over (partition by cid)
else avg (val) over (partition by 1)
end as avg
from @tbl;
http://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=fdf4c4457220ec64132de7452a034976
cid avg
100 31.2
200 38.25
300 38.25
像这样的查询有很多方面,虽然在规模上运行虽然在查询计划上会非常糟糕,但我想在更大的范围内进行测试并在使用前进行调整。
描述不清楚发生了什么,如果它正好是3,它提到“超过3”和“少于3” - 在这段代码中,“超过”用于确定它所属的类别,以及小于被解释为'小于或等于3'