SQL – 根据条件创建多个列的填充率,并使用 GROUP BY

huangapple go评论51阅读模式
英文:

SQL - Create multiple columns for fill rates based on conditions, with GROUP BY

问题

以下是翻译好的代码部分:

-- 创建临时表
CREATE TABLE #TempTable (
    ID varchar(10),
    GroupCD varchar(10),
    SurrogateKEY1 varchar(10),
    SurrogateKEY2 varchar(10)
)

-- 插入示例数据
INSERT INTO #TempTable (ID, GroupCD, SurrogateKEY1, SurrogateKEY2)
VALUES 
    ('1', 'UNK', '12345', '89225'),
    ('3', 'ABC', NULL, '44658'),
    ('3', 'DEF', NULL, '99658'),
    ('5', 'ABC', '09184', NULL),
    ('4', 'DEF', NULL, '85598'),
    ('1', 'GHI', '80642', '77890')
-- 计算SurrogateKey列的填充率,按ID分组
SELECT
    ID,
    CAST(SUM(CASE WHEN SurrogateKEY1 IS NULL THEN 0 ELSE 1 END) / CAST(COUNT(1) AS FLOAT) * 100 AS Decimal(8,3)) AS SurrogateKEY1_fR,
    CAST(SUM(CASE WHEN SurrogateKEY2 IS NULL THEN 0 ELSE 1 END) / CAST(COUNT(1) AS FLOAT) * 100 AS Decimal(8,3)) AS SurrogateKEY2_fR
FROM #TempTable
GROUP BY ID
-- 扩展查询以基于GroupCD = 'ABC' 或其他代码计算填充率
SELECT
    ID,
    CAST(SUM(CASE WHEN GroupCD <> 'ABC' THEN CASE WHEN SurrogateKEY1 IS NULL THEN 0 ELSE 1 END ELSE 0 END) / CAST(COUNT(1) AS FLOAT) * 100 AS Decimal(8,3)) AS SurrogateKEY1_fR_NonABC,
    CAST(SUM(CASE WHEN GroupCD = 'ABC' THEN CASE WHEN SurrogateKEY1 IS NULL THEN 0 ELSE 1 END ELSE 0 END) / CAST(COUNT(1) AS FLOAT) * 100 AS Decimal(8,3)) AS SurrogateKEY1_fR_ClassFilterABC,
    CAST(SUM(CASE WHEN GroupCD <> 'ABC' THEN CASE WHEN SurrogateKEY2 IS NULL THEN 0 ELSE 1 END ELSE 0 END) / CAST(COUNT(1) AS FLOAT) * 100 AS Decimal(8,3)) AS SurrogateKEY2_fR_NonABC,
    CAST(SUM(CASE WHEN GroupCD = 'ABC' THEN CASE WHEN SurrogateKEY2 IS NULL THEN 0 ELSE 1 END ELSE 0 END) / CAST(COUNT(1) AS FLOAT) * 100 AS Decimal(8,3)) AS SurrogateKEY2_fR_ClassFilterABC
FROM #TempTable
GROUP BY ID

希望这些翻译对你有所帮助。

英文:

Some example data:

CREATE TABLE #TempTable (

ID varchar(10),
GroupCD varchar(10),
SurrogateKEY1 varchar(10),
SurrogateKEY2 varchar(10)

)

INSERT INTO #TempTable (ID, GroupCD, SurrogateKEY1, SurrogateKEY2)
VALUES 
    (&#39;1&#39;, &#39;UNK&#39;, &#39;12345&#39;, &#39;89225&#39;),
    (&#39;3&#39;, &#39;ABC&#39;, NULL, &#39;44658&#39;),
    (&#39;3&#39;, &#39;DEF&#39;, NULL, &#39;99658&#39;),
    (&#39;5&#39;, &#39;ABC&#39;, &#39;09184&#39;, NULL),
    (&#39;4&#39;, &#39;DEF&#39;, NULL, &#39;85598&#39;),
    (&#39;1&#39;, &#39;GHI&#39;, &#39;80642&#39;, &#39;77890&#39;)
ID GroupCD SurrogateKEY1 SurrogateKEY2
1 UNK 12345 89225
3 ABC NULL 44658
3 DEF NULL 99658
5 ABC 09184 NULL
4 DEF NULL 85598
1 GHI 80642 77890

I would like to calculate the fill rates for the SurrogateKey columns, grouped by the IDs, which I have code for:

SELECT
    ID,
    CAST(SUM(CASE WHEN SurrogateKEY1 IS NULL THEN 0 ELSE 1 END) / CAST(COUNT(1) AS FLOAT) * 100 AS Decimal(8,3)) AS SurrogateKEY1_fR,
    CAST(SUM(CASE WHEN SurrogateKEY2 IS NULL THEN 0 ELSE 1 END) / CAST(COUNT(1) AS FLOAT) * 100 AS Decimal(8,3)) AS SurrogateKEY2_fR
FROM #TempTable
GROUP BY ID
ID SurrogateKEY1_fR SurrogateKEY2_fR
1 100.000 100.000
3 0.000 100.000
4 0.000 100.000
5 100.000 0.000

I'd like to expand this query so the fill rate calculation will be based on the GroupCD = 'ABC' or every other code.

I would like the output to be:

ID SurrogateKEY1_fR_NonABC SurrogateKEY1_fR_ClassFilterABC SurrogateKEY2_fR_NonABC SurrogateKEY2_fR_ClassFilterABC
1 100.000 0.000 100.000 0.000
3 0.000 0.000 100.000 100.000
4 0.000 0.000 100.000 0.000
5 0.000 100.000 0.000 0.000

Does anybody know how to leverage CASE statements or another avenue in order to produce this output?

答案1

得分: 2

以下是翻译好的代码部分:

SELECT
    ID,
    CAST(SUM(CASE WHEN GroupCD &lt;&gt; 'ABC' AND SurrogateKEY1 IS NOT NULL THEN 1 ELSE 0 END) / CAST(COUNT(1) AS FLOAT) * 100 AS Decimal(8,3)) AS SurrogateKEY1_fR_NonABC,
    CAST(SUM(CASE WHEN GroupCD = 'ABC' AND SurrogateKEY1 IS NOT NULL THEN 1 ELSE 0 END) / CAST(COUNT(1) AS FLOAT) * 100 AS Decimal(8,3)) AS SurrogateKEY1_fR_ClassFilterABC,
    CAST(SUM(CASE WHEN GroupCD &lt;&gt; 'ABC' AND SurrogateKEY2 IS NOT NULL THEN 1 ELSE 0 END) / CAST(COUNT(1) AS FLOAT) * 100 AS Decimal(8,3)) AS SurrogateKEY2_fR_NonABC,
    CAST(SUM(CASE WHEN GroupCD = 'ABC' AND SurrogateKEY2 IS NOT NULL THEN 1 ELSE 0 END) / CAST(COUNT(1) AS FLOAT) * 100 AS Decimal(8,3)) AS SurrogateKEY2_fR_ClassFilterABC
FROM #TempTable
GROUP BY ID

请注意,上述代码是SQL查询的一部分,用于计算不同条件下的百分比。

英文:

Its can be done this way :

SELECT
    ID,
    CAST(SUM(CASE WHEN GroupCD &lt;&gt; &#39;ABC&#39; AND SurrogateKEY1 IS NOT NULL THEN 1 ELSE 0 END) / CAST(COUNT(1) AS FLOAT) * 100 AS Decimal(8,3)) AS SurrogateKEY1_fR_NonABC,
    CAST(SUM(CASE WHEN GroupCD = &#39;ABC&#39; AND SurrogateKEY1 IS NOT NULL THEN 1 ELSE 0 END) / CAST(COUNT(1) AS FLOAT) * 100 AS Decimal(8,3)) AS SurrogateKEY1_fR_ClassFilterABC,
    CAST(SUM(CASE WHEN GroupCD &lt;&gt; &#39;ABC&#39; AND SurrogateKEY2 IS NOT NULL THEN 1 ELSE 0 END) / CAST(COUNT(1) AS FLOAT) * 100 AS Decimal(8,3)) AS SurrogateKEY2_fR_NonABC,
    CAST(SUM(CASE WHEN GroupCD = &#39;ABC&#39; AND SurrogateKEY2 IS NOT NULL THEN 1 ELSE 0 END) / CAST(COUNT(1) AS FLOAT) * 100 AS Decimal(8,3)) AS SurrogateKEY2_fR_ClassFilterABC
FROM #TempTable
GROUP BY ID

The result is a little bit different that you expected :

Demo here

答案2

得分: 1

我建议使用 CTEPIVOT

;WITH CTE AS
( 
 SELECT ID,
   GrpKey = CASE WHEN GroupCD = 'ABC' THEN GroupCD ELSE 'NonABC' END,
   SurrogateKEY1fr = CASE WHEN SurrogateKEY1 IS NULL THEN 0.0 ELSE 1.0 END,
   SurrogateKEY2fr = CASE WHEN SurrogateKEY2 IS NULL THEN 0.0 ELSE 1.0 END
 FROM TempTable
),
P1 AS
(
 SELECT ID, [ABC] AS ABCKEY1fr, [NonABC] AS NonABCKEY1fr
 FROM CTE AS DT
 PIVOT(MAX(SurrogateKEY1fr) FOR GrpKey IN([ABC], [NonABC])) AS PVT
),
P2 AS
(
SELECT ID, [ABC] AS ABCKEY2fr, [NonABC] AS NonABCKEY2fr
 FROM CTE AS DT
 PIVOT(MAX(SurrogateKEY2fr) FOR GrpKey IN([ABC], [NonABC])) AS PVT
) 
SELECT P1.ID, COALESCE(P1.ABCKEY1fr, 0.0) * 100.0 AS ABCKEY1fr, 
  COALESCE(P1.NonABCKEY1fr, 0.0) * 100.0 AS NonABCKEY1fr, 
  COALESCE(P2.ABCKEY2fr, 0.0) * 100.0 AS ABCKEY2fr,
  COALESCE(P2.NonABCKEY2fr, 0.0) * 100.0 AS NonABCKEY2fr
FROM P1
INNER JOIN P2
  ON P2.ID = P1.ID;

SQL Fiddle

英文:

I'd suggest to use CTE and PIVOT.

;WITH CTE AS
( 
 SELECT ID,
   GrpKey = CASE WHEN GroupCD = &#39;ABC&#39; THEN GroupCD ELSE &#39;NonABC&#39; END,
   SurrogateKEY1fr = CASE WHEN SurrogateKEY1 IS NULL THEN 0.0 ELSE 1.0 END,
   SurrogateKEY2fr = CASE WHEN SurrogateKEY2 IS NULL THEN 0.0 ELSE 1.0 END
 FROM TempTable
),
P1 AS
(
 SELECT ID, [ABC] AS ABCKEY1fr, [NonABC] AS NonABCKEY1fr
 FROM CTE AS DT
 PIVOT(MAX(SurrogateKEY1fr) FOR GrpKey IN([ABC], [NonABC])) AS PVT
),
P2 AS
(
SELECT ID, [ABC] AS ABCKEY2fr, [NonABC] AS NonABCKEY2fr
 FROM CTE AS DT
 PIVOT(MAX(SurrogateKEY2fr) FOR GrpKey IN([ABC], [NonABC])) AS PVT
) 
SELECT P1.ID, COALESCE(P1.ABCKEY1fr, 0.0) * 100.0 AS ABCKEY1fr, 
  COALESCE(P1.NonABCKEY1fr, 0.0) * 100.0 AS NonABCKEY1fr, 
  COALESCE(P2.ABCKEY2fr, 0.0) * 100.0 AS ABCKEY2fr,
  COALESCE(P2.NonABCKEY2fr, 0.0) * 100.0 AS NonABCKEY2fr
FROM P1
INNER JOIN P2
  ON P2.ID = P1.ID;

SQL Fiddle

答案3

得分: 1

不需要分开两个COUNT()函数的结果。<br/>
您可以使用AVG()聚合函数简化条件聚合:

SELECT ID,
       100 * AVG(CASE WHEN GroupCD &lt;&gt; 'ABC' AND SurrogateKEY1 IS NOT NULL THEN 1.0 ELSE 0.0 END) AS SurrogateKEY1_fR_NonABC,	
       100 * AVG(CASE WHEN GroupCD = 'ABC' AND SurrogateKEY1 IS NOT NULL THEN 1.0 ELSE 0.0 END) AS SurrogateKEY1_fR_ClassFilterABC,	
       100 * AVG(CASE WHEN GroupCD &lt;&gt; 'ABC' AND SurrogateKEY2 IS NOT NULL THEN 1.0 ELSE 0.0 END) AS SurrogateKEY2_fR_NonABC,	
       100 * AVG(CASE WHEN GroupCD = 'ABC' AND SurrogateKEY2 IS NOT NULL THEN 1.0 ELSE 0.0 END) AS SurrogateKEY2_fR_ClassFilterABC 
FROM #TempTable
GROUP BY ID;

请参见[演示][1]&lt;br/&gt;

  [1]: https://dbfiddle.uk/JPOumTPr


<details>
<summary>英文:</summary>

There is no need to divide the results of 2 aggregate `COUNT()`s.&lt;br/&gt; 
You can simplify the conditional aggregation with `AVG()` aggregate function:

    SELECT ID,
           100 * AVG(CASE WHEN GroupCD &lt;&gt; &#39;ABC&#39; AND SurrogateKEY1 IS NOT NULL THEN 1.0 ELSE 0.0 END) AS SurrogateKEY1_fR_NonABC,	
           100 * AVG(CASE WHEN GroupCD = &#39;ABC&#39; AND SurrogateKEY1 IS NOT NULL THEN 1.0 ELSE 0.0 END) AS SurrogateKEY1_fR_ClassFilterABC,	
           100 * AVG(CASE WHEN GroupCD &lt;&gt; &#39;ABC&#39; AND SurrogateKEY2 IS NOT NULL THEN 1.0 ELSE 0.0 END) AS SurrogateKEY2_fR_NonABC,	
           100 * AVG(CASE WHEN GroupCD = &#39;ABC&#39; AND SurrogateKEY2 IS NOT NULL THEN 1.0 ELSE 0.0 END) AS SurrogateKEY2_fR_ClassFilterABC 
    FROM #TempTable
    GROUP BY ID;

See the [demo][1].&lt;br/&gt;


  [1]: https://dbfiddle.uk/JPOumTPr

</details>



huangapple
  • 本文由 发表于 2023年3月4日 04:18:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/75631539.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定