sql >> データベース >  >> RDS >> Sqlserver

合計値のパーセンテージを超える行のサブセットの選択

    SQL Server 2012+ のみ

    ウィンドウ化された SUM を使用できます :

    WITH cte AS( SELECT *, 1.0 * Revenue/SUM(Revenue) OVER(PARTITION BY [User]) AS パーセンタイル, 1.0 * SUM(Revenue) OVER(PARTITION BY [User] ORDER BY [Revenue] DESC) /SUM(収益) OVER(PARTITION BY [ユーザー]) AS running_percentile FROM tab)SELECT *FROM cte WHERE running_percentile <=0.8;  

    LiveDemo

    SQL Server 2008:

    WITH cte AS( SELECT *, ROW_NUMBER() OVER(PARTITION BY [User] ORDER BY Revenue DESC) AS rn FROM t ), cte2 AS( SELECT c.Customer, c.[User], c. [収益] ,パーセンタイル =1.0 * 収益 / NULLIF(c3.s,0) ,running_percentile =1.0 * c2.s / NULLIF(c3.s,0) FROM cte c CROSS APPLY (SELECT SUM(Revenue) AS s FROM cte c2 WHERE c.[User] =c2.[User] AND c2.rn <=c.rn) c2 CROSS APPLY (SELECT SUM(Revenue) AS s FROM cte c2 WHERE c.[User] =c2.[User]) AS c3) SELECT *FROM cte2WHERE running_percentile <=0.8;  

    LiveDemo2

    出力:

    ╔══════════╦═══════╦═════════╦═════════════════════════════ ══╦════════════════════╗║ Customer ║ User ║ Revenue ║ percentile ║ running_percentile ║╠══════════╬═══ ════╬═════════╬════════════════╬══════════════════ ══╣║ 2 ║ James ║ 750 ║ 0,384615384615 ║ 0,384615384615 ║║ 1 ║ James ║ 500 ║ 0,256410256410 ║ 0,641025641025 ║║ 7 ║ Sarah ║ 600 ║ 0,444444444444 ║ 0,444444444444 ║╚═ ═════════╩═══════╩═════════╩════════════════╩═════ ═══════════════╝  

    編集 2:

    WITH cte AS( SELECT *, ROW_NUMBER() OVER(PARTITION BY [User] ORDER BY Revenue DESC) AS rn FROM t ), cte2 AS( SELECT c.Customer, c.[User], c. [収益] ,パーセンタイル =1.0 * 収益 / NULLIF(c3.s,0) ,running_percentile =1.0 * c2.s / NULLIF(c3.s,0) FROM cte c CROSS APPLY (SELECT SUM(Revenue) AS s FROM cte c2 WHERE c.[User] =c2.[User] AND c2.rn <=c.rn) c2 CROSS APPLY (SELECT SUM(Revenue) AS s FROM cte c2 WHERE c.[User] =c2.[User]) AS c3) SELECT a.*FROM cte2 aCROSS APPLY (SELECT MIN(running_percentile) AS rp FROM cte2 WHERE running_percentile>=0.8 AND cte2.[User] =a.[User]) AS sWHERE a.running_percentile <=s.rp;   

    LiveDemo3

    出力:

    ╔══════════╦═══════╦═════════╦═════════════════════════════ ══╦════════════════════╗║ Customer ║ User ║ Revenue ║ percentile ║ running_percentile ║╠══════════╬═══ ════╬═════════╬════════════════╬══════════════════ ══╣║ 2 ║ James ║ 750 ║ 0,384615384615 ║ 0,384615384615 ║║ 1 ║ James ║ 500 ║ 0,256410256410 ║ 0,641025641025 ║║ 3 ║ James ║ 450 ║ 0,230769230769 ║ 0,871794871794 ║║ 7 ║ Sarah ║ 600 ║ 0,444444444444 ║ 0,444444444444 ║║ 5 ║ Sarah ║ 500 ║ 0,370370370370 ║ 0,814814814814 ║╚══════════╩═══════╩══ ═══════╩════════════════╩════════════════════════════════════════════  

    SQL Server 2008 OVER() のすべてをサポートしているわけではありません 節ですが、ROW_NUMBER

    最初に、グループ内の位置を計算します:

    ╔═══════════╦════════╦══════════╦════║║ 顧客 ══╦════║║ 顧客║ rn ║╠═══════════╬════════╬══════════╬════╣║ 2 ║ James ║ 750 ║ 1 ║ ║ 1 ║ James ║ 500 ║ 2 ║║ 3 ║ James ║ 450 ║ 3 ║║ 8 ║ James ║ 150 ║ 4 ║║ 9 ║ James ║ 100 ║ 5 ║║ 7 ║ Sarah ║ 600 ║ 1 ║║ 5 ║ Sarah ║ 500 ║ 2 ║║ 6 ║ Sarah ║ 150 ║ 3 ║║ 4 ║ Sarah ║ 100 ║ 4 ║╚═══════════╩════════╩══════ ════╩════╝  

    2 番目の cte:

    • c2 サブクエリは、ROW_NUMBER からのランクに基づいて実行中の合計を計算します
    • c3 ユーザーあたりの全額を計算

    最後のクエリ s で サブクエリは、最低の running を見つけます 合計が 80% を超えています。

    編集 3:

    ROW_NUMBER の使用 は実際には冗長です。

    WITH cte AS( SELECT c.Customer, c.[User], c.[Revenue] ,percentile =1.0 * Revenue / NULLIF(c3.s,0) ,running_percentile =1.0 * c2.s / NULLIF(c3.s,0) FROM t c CROSS APPLY (SELECT SUM(Revenue) AS s FROM t c2 WHERE c.[User] =c2.[User] AND c2.Revenue>=c.Revenue) c2 CROSS APPLY (SELECT SUM(Revenue) AS s FROM t c2 WHERE c.[User] =c2.[User]) AS c3) SELECT a.*FROM cte aCROSS APPLY (SELECT MIN(running_percentile) AS rp FROM cte c2 WHERE running_percentile>=0.8 AND c2.[User] =a.[User]) AS sWHERE a.running_percentile <=s.rpORDER BY [User], Revenue DESC;  

    LiveDemo4



    1. 2012年のレコードを取得するための休止状態の基準

    2. PHPでのMySQLストアドプロシージャの呼び出し

    3. 移行実行時の外部キーエラーを修正する方法

    4. PHPの致命的なエラー:未定義の関数mysql_connect()の呼び出し