1

私には異常な状況があります。次のコードを検討してください。

IF OBJECT_ID('tempdb..#CharacterTest') IS NOT NULL
    DROP TABLE #CharacterTest

CREATE TABLE #CharacterTest
(
  [ID] int IDENTITY(1, 1) NOT NULL,
[CharField] varchar(50) NULL 
)


INSERT INTO #CharacterTest (CharField)
VALUES  ('A')
      , ('A')
      , ('A')
      , ('A')
      , ('B')
      , ('B')
      , ('B')
      , ('C')
      , ('C')
      , ('D')
      , ('D')
      , ('F')
      , ('G')
      , ('H')
      , ('I')
      , ('J')
      , ('K')
      , ('L')
      , ('M')
      , ('N')
      , (' ')
      , (' ')
      , (' ')
      , (NULL)
      , ('');

A (16%)、B (12%)、C(8%) のような文字列を返すクエリが欲しいです。

次の点に注意してください。

  • 空の文字列、すべてが空白の文字列、または NULL が上位 3 にリストされるのは望ましくありませんが、テーブルのレコード数全体を使用して計算された値のパーセンテージが必要です。
  • 同点は無視できるので、リストに 22 個の値があり、頻度が 8% の場合は、最初の値を返すだけで問題ありません。
  • パーセンテージは整数に丸めることができます。

T-SQL との互換性を維持しながら、SQL Server 2005 との互換性を維持しながら、このクエリを作成する最も簡単な方法を見つけたいと思います。これを行う最善の方法は何ですか? ウィンドウ関数?

4

3 に答える 3

2

これにより、必要な文字列が取得されます。

declare @output varchar(200);

with cte as (
    select CharField
        , (count(*) * 100) / (select count(*) from #CharacterTest) as CharPct
        , row_number() over (order by count(*) desc, CharField) as RowNum
    from #CharacterTest
    where replace(CharField, ' ', '') not like ''
    group by CharField
)
select @output = coalesce(@output + ', ', '') + CharField + ' (' + cast(CharPct as varchar(11)) + '%)'
from cte
where RowNum <= 3
order by RowNum;

select @output;

-- Returns:
-- A (16%), B (12%), C (8%)

varchar(50)ただし、1 つの文字を列に格納することに注意してください。

于 2013-04-29T20:48:46.013 に答える
2

私の最初の試みはおそらくこれでしょう。それがそれを処理するための最良の方法であると言っているわけではありませんが、うまくいくでしょう.

DECLARE @TotalCount INT
SELECT @TotalCount = COUNT(*) FROM #CharacterTest AS ct

SELECT TOP(3) CharField, COUNT(*) * 1.0 / @TotalCount AS OverallPercentage
FROM #CharacterTest AS ct
WHERE CharField IS NOT NULL AND REPLACE(CharField, ' ', '') <> ''
GROUP BY CharField
ORDER BY COUNT(*) desc

DROP TABLE #CharacterTest
于 2013-04-29T20:23:01.737 に答える