SQL Server已经过了COUNT OVER问题

时间:2016-04-15 14:02:09

标签: sql-server count

我有以下查询:

SELECT DISTINCT
    x.CountryID [code], 
    c.Description [name],
    COUNT(x.username) OVER(PARTITION BY x.countryID) [count],
    COUNT(x.username) OVER () [tcount],
    COALESCE(c.Map,'world') [map]
FROM
(
    SELECT DISTINCT 
        CountryID, 
        username, 
        Score
    FROM global.dbo.UserCategories
    WHERE TLCID LIKE @TLCID OR TLCID IN (@TLCID)
) x
JOIN global.dbo.countrydetails c on x.CountryID=c.country
AND x.Score BETWEEN @ScoreMin AND @ScoreMax
GROUP BY x.CountryID, c.Description, c.Map, x.username --WITH ROLLUP
--HAVING COUNT(x.username) OVER(PARTITION BY x.countryID)>@Min
ORDER BY [name] ASC

为每个国家/地区显示具有特定分数且在某些类别中有效的用户数 我想从列表中排除用户很少的国家/地区 我想添加HAVING子句 但是sql告诉我

  

"窗口函数只能出现在SELECT或ORDER BY中   条款"

最重要的表是CountryDetails,如下所示:

CountryID   username    score       TLCID
    DE      12-bu       19598       131090
    DE      12-bu       19598       220
    DE      12-bu       19598       11700
    DE      12-bu       19598       131090
    DE      1buy3       19648       11700
    DE      1buy3       19648       11450
    DE      1buy3       19648       11700
    DE      1buy3       19648       11700
    CN      2012f       22780       11450
    CN      2012f       22780       11450
    CN      2012f       22780       11450
    CN      2012f       22780       11450
    CN      2012f       22780       11450
    GB      agood       74539       1
    GB      agood       74539       11450
    GB      agood       74539       12576
    GB      agood       74539       131090
    GB      agood       74539       1
    GB      agood       74539       11233
    GB      agood       74539       1
    GB      agood       74539       1
    GB      agood       74539       1
    GB      agood       74539       220
    BG      best0       3173        2984
    IT      bestb       13777       15032
    IT      bestb       13777       293
    IT      bestb       13777       293
    IT      bestb       13777       15032
    IT      bestb       13777       15032
    IT      bestb       13777       15032
    IT      bestb       13777       58058
    IT      bestb       13777       293
    DE      bestb       55165       131090
    DE      bestb       55165       293
    DE      bestb       55165       293
    DE      bestb       55165       293
    DE      bestb       55165       293
    CN      besto       24537       11450
    GB      bidan       4584        58058
    GB      bidan       4584        58058
    IT      bimbu       4145        11700
    GB      buy_d       97093       12576
    GB      buy_d       97093       888
    GB      buy_d       97093       888
    GB      buy_d       97093       888
    GB      buy_d       97093       159912
    GB      buy_d       97093       888
    GB      buy_d       97093       159912
    GB      buy_d       97093       11700
    GB      buy_d       97093       11700
    GB      buy_d       97093       159912
    GB      buy_d       97093       20710
    GB      buy_d       97093       159912
    GB      buy_d       97093       888
    GB      buy_s       988538      11232
    GB      buy_s       988538      1
    GB      buy_s       988538      11700
    GB      buy_s       988538      26395

关于结果..现在我得到了这个

code    name        count       tcount  map
AD      Andorra         3       83141   andorra
AU      Australia       14      83141   australia
AT      Austria         345     83141   austria
.....
BE      Belgium         28      83141   belgium
CN      China           1070    83141   china
FR      France          4732    83141   france
DE      Germany         33782   83141   germany
HK      Hong Kong       364     83141   hongKong
HU      Hungary         9       83141   hungary
.....
IN      India           10      83141   india
IR      Iran            1       83141   iran
IQ      Iraq            17      83141   iraq
IE      Ireland         36      83141   ireland
IL      Israel          16      83141   israel
IT      Italy           5427    83141   italy
JE      Jersey          25      83141   world
....
GB      United Kingdom  35136   83141   unitedKingdom

...

假设将@Min设置为20我想得到这个:

code    name            count   tcount  map
AT      Austria         345     80945   austria
BE      Belgium         28      80945   belgium
CN      China           1070    80945   china
FR      France          4732    80945   france
DE      Germany         33782   80945   germany
HK      Hong Kong       364     80945   hongKong
IE      Ireland         36      80945   ireland
IT      Italy           5427    80945   italy
JE      Jersey          25      80945   world
GB      United Kingdom  35136   80945   unitedKingdom

其中tcount是计数总和

Pls可以建议解决方法的路径吗?

谢谢!

3 个答案:

答案 0 :(得分:1)

you might be able to do something as simple as this..

SELECT  c.countryid,
        c.[description],
        x.[count],
        SUM([count]) OVER () [tcount],
        COALESCE(c.Map,'world') [map]
FROM    global.dbo.countrydetails c
        OUTER APPLY (
            SELECT  COUNT(DISTINCT uc.username) [count]
            FROM    global.dbo.UserCategories uc
            WHERE   uc.countryid = c.countryid
                    AND TLCID LIKE @TLCID OR TLCID IN (@TLCID)
                    AND uc.Score BETWEEN @ScoreMin AND @ScoreMax
        ) x
WHERE   x.[count] > @Min

it will select the individual username counts and apply them to the countries.. then you can sum the counts to get tcount and filter on the individual counts

SQL Fiddle

答案 1 :(得分:0)

你似乎离这里很近。我认为你让它变得比它需要的更复杂。此外,subselect中的where子句不太正确。它可以简化为等于。

这应该非常接近。

SELECT DISTINCT
    x.CountryID [code], 
    c.Description [name],
    COUNT(x.username) as [tcount],
    COALESCE(c.Map,'world') [map]
FROM
(
    SELECT DISTINCT 
        CountryID, 
        username, 
        Score
    FROM global.dbo.UserCategories
    WHERE TLCID = @TLCID
) x
JOIN global.dbo.countrydetails c on x.CountryID=c.country
AND x.Score BETWEEN @ScoreMin AND @ScoreMax
GROUP BY x.CountryID, c.Description, c.Map
HAVING COUNT(x.username) > @Min
ORDER BY [name] ASC

- 编辑 -

要弄清楚你想要什么是很有挑战性的,因为我们没有表格,没有样本数据,没有所需的输出。简而言之,任何人现在都可以做的最好的事情就是猜你想要什么。这是一篇很好的文章,解释了你应该在网上论坛上发布t-sql帮助的内容。 http://spaghettidba.com/2015/04/24/how-to-post-a-t-sql-question-on-a-public-forum/

这是你可能想要的另一个猜测。我注意到你有不同的分组。这是多余的。

with CompiledValues as
(
    SELECT x.CountryID as [code], 
        c.Description as [name],
        COUNT(x.username) OVER(PARTITION BY x.countryID) as [count],
        COUNT(x.username) OVER () as [tcount],
        COALESCE(c.Map,'world') [map]
    FROM
    (
        SELECT DISTINCT 
            CountryID, 
            username
        FROM global.dbo.UserCategories
        WHERE TLCID = @TLCID
    ) x
    JOIN global.dbo.countrydetails c on x.CountryID = c.country
        AND x.Score BETWEEN @ScoreMin AND @ScoreMax
    GROUP BY x.CountryID
        , c.Description
        , c.Map
)

select *
from CompiledValues
where tcount > @Min
ORDER BY [name] ASC

答案 2 :(得分:0)

您似乎希望在选择国家/用户名时做出此决定。问题是用户是否可以拥有> 1分,如果你想要这部分确定你的门槛数。

-- Filtering by Count of CountryID, username, Score
SELECT DISTINCT
    x.CountryID [code], 
    c.Description [name],
    COUNT(x.username) OVER(PARTITION BY x.countryID) [count],
    COUNT(x.username) OVER () [tcount],
    COALESCE(c.Map,'world') [map]
FROM
(
    SELECT COUNT(*), 
        CountryID, 
        username, 
        Score
    FROM global.dbo.UserCategories
    WHERE TLCID LIKE @TLCID OR TLCID IN (@TLCID)
    GROUP BY CountryID, 
        username, 
        Score
    HAVING COUNT(*) > [Your_Threshold_Number]
) x
JOIN global.dbo.countrydetails c on x.CountryID=c.country
AND x.Score BETWEEN @ScoreMin AND @ScoreMax
GROUP BY x.CountryID, c.Description, c.Map, x.username
ORDER BY [name] ASC

-- Filtering by Count of CountryID, username
SELECT DISTINCT
    x.CountryID [code], 
    c.Description [name],
    COUNT(x.username) OVER(PARTITION BY x.countryID) [count],
    COUNT(x.username) OVER () [tcount],
    COALESCE(c.Map,'world') [map]
FROM
(
    SELECT COUNT(*), 
        CountryID, 
        username, 
        Score
    FROM global.dbo.UserCategories AS g1
    JOIN ( SELECT COUNT(*) AS Cnt, 
        CountryID, 
        username
    FROM global.dbo.UserCategories
    GROUP BY CountryID, 
        username
    HAVING COUNT(*) > [Your_Threshold_Number]
    ) g2 ON g1.CountryID = g2.CountryID
    WHERE TLCID LIKE @TLCID OR TLCID IN (@TLCID)
    GROUP BY CountryID, 
        username, 
        Score
) x
JOIN global.dbo.countrydetails c on x.CountryID=c.country
AND x.Score BETWEEN @ScoreMin AND @ScoreMax
GROUP BY x.CountryID, c.Description, c.Map, x.username
ORDER BY [name] ASC