Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Tsql 字符字段中前3位值的百分比_Tsql_Sql Server 2005_Window Functions - Fatal编程技术网

Tsql 字符字段中前3位值的百分比

Tsql 字符字段中前3位值的百分比,tsql,sql-server-2005,window-functions,Tsql,Sql Server 2005,Window Functions,我有一个不寻常的情况。请考虑以下代码: 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 (

我有一个不寻常的情况。请考虑以下代码:

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%,C8%

请注意以下事项:

我不希望在前三名中列出空字符串、带所有空格的字符串或空字符串,但我希望使用表的整个记录计数计算值的百分比。 可以忽略关系,因此如果列表中有22个值的频率为8%,则可以简单地返回第一个值。 百分比可以四舍五入为整数。
我希望找到编写此查询的最简单方法,同时仍保持T-SQL与SQLServer2005的兼容性。最好的方法是什么?窗口功能

我的第一次尝试可能是这样。不是说这是最好的处理方法,而是说它会起作用

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

我的第一次尝试可能是这样。不是说这是最好的处理方法,而是说它会起作用

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

这将获得所需的字符串:

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%)

不过,我想提醒大家注意在varchar50列中存储一个字符。

这将获得您需要的字符串:

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%)
不过,我想提醒大家注意在varchar50列中存储一个字符。

我会选择

WITH T1
     AS (SELECT [CharField],
                100.0 * COUNT(*) OVER (PARTITION BY [CharField]) / 
                                             COUNT(*) OVER () AS Pct
         FROM   #CharacterTest),
     T2
     AS (SELECT DISTINCT TOP 3 *
         FROM   T1
         WHERE  [CharField] <> '' --Excludes all blank or NULL as well
         ORDER  BY Pct DESC)
SELECT STUFF((SELECT ',' + [CharField] + ' (' + CAST(CAST(ROUND(Pct,1) AS INT) AS VARCHAR(3)) + ')'
              FROM   T2
              ORDER BY Pct DESC
              FOR XML PATH('')), 1, 1, '') AS Result 
我会去的

WITH T1
     AS (SELECT [CharField],
                100.0 * COUNT(*) OVER (PARTITION BY [CharField]) / 
                                             COUNT(*) OVER () AS Pct
         FROM   #CharacterTest),
     T2
     AS (SELECT DISTINCT TOP 3 *
         FROM   T1
         WHERE  [CharField] <> '' --Excludes all blank or NULL as well
         ORDER  BY Pct DESC)
SELECT STUFF((SELECT ',' + [CharField] + ' (' + CAST(CAST(ROUND(Pct,1) AS INT) AS VARCHAR(3)) + ')'
              FROM   T2
              ORDER BY Pct DESC
              FOR XML PATH('')), 1, 1, '') AS Result 

在我的盒子上没有变量和比我的头发快的头发…尼斯在我的盒子上没有变量和比我的头发快的头发…尼斯