SQL Server:由select语句分组给出错误

时间:2014-01-23 13:18:53

标签: sql sql-server

我有两张桌子:

  • PersonTBL table:包含存储Person
  • 的IP地址的列HostAddress
  • ip-to-country表:包含国家/地区的IP号码范围

我正在尝试计算每个国家的人数,但我收到了一个错误:

  

无效的列名称“CountryName”。

查询:

SELECT  
    Count(HostAddress) as TotalNo,
    (select [ip-to-country].CountryName 
     from [ip-to-country] 
     where ((CAST(PARSENAME(HostAddress, 4) AS Bigint) * 256 * 256 * 256) + 
            (CAST(PARSENAME(HostAddress, 3) AS INT) * 256 * 256) + 
            (CAST(PARSENAME(HostAddress, 2) AS INT) * 256) + 
             CAST(PARSENAME(HostAddress, 1) AS INT))
            BETWEEN [ip-to-country].BegingIP AND [ip-to-country].EndIP) AS CountryName
FROM PersonTBL 
GROUP BY
   CountryName

我也尝试过:

SELECT  
    Count(HostAddress) as TotalNo,
    (SELECT [ip-to-country].CountryName 
     FROM [ip-to-country] 
     WHERE 
        ((CAST(PARSENAME(HostAddress, 4) AS Bigint) * 256 * 256 * 256) + 
         (CAST(PARSENAME(HostAddress, 3) AS INT) * 256 * 256) +
         (CAST(PARSENAME(HostAddress, 2) AS INT) * 256) +
         CAST(PARSENAME(HostAddress, 1) AS INT)) BETWEEN [ip-to-country].BegingIP AND [ip-to-country].EndIP) as CountryName
FROM PersonTBL 
GROUP BY 
    (SELECT [ip-to-country].CountryName 
     FROM [ip-to-country] 
     WHERE 
        ((CAST(PARSENAME(HostAddress, 4) AS Bigint) * 256 * 256 * 256) + 
         (CAST(PARSENAME(HostAddress, 3) AS INT) * 256 * 256) +
         (CAST(PARSENAME(HostAddress, 2) AS INT) * 256) +
         CAST(PARSENAME(HostAddress, 1) AS INT)) BETWEEN [ip-to-country].BegingIP AND [ip-to-country].EndIP) as CountryName

但我收到了另一个错误:

  

不能在用于GROUP BY子句列表的表达式中使用聚合或子查询。

任何人都可以帮我按国家/地区分组用户吗?

3 个答案:

答案 0 :(得分:3)

如果您只定义该别名,则不能直接在GROUP BY上使用列别名,您可以在GROUP BY上使用相同的表达式,也可以使用派生表或CTE:

派生表:

SELECT  COUNT(HostAddress) AS TotalNo, 
        CountryName
FROM (  SELECT  HostAddress,
                (SELECT [ip-to-country].CountryName 
                 FROM [ip-to-country] 
                 WHERE 
                 ((CAST(PARSENAME(HostAddress, 4) AS BIGINT)*256*256*256) + 
                 (CAST(PARSENAME(HostAddress, 3) AS INT)*256*256)
                  + (CAST(PARSENAME(HostAddress, 2) AS INT)*256) 
                  + CAST(PARSENAME(HostAddress, 1) AS INT))
                 BETWEEN  [ip-to-country].BegingIP and [ip-to-country].EndIP) AS CountryName
         FROM PersonTBL) T
 GROUP BY CountryName

CTE(SQL Server 2005 +):

;WITH CTE AS
(
    SELECT  HostAddress,
            (SELECT [ip-to-country].CountryName 
             FROM [ip-to-country] 
             WHERE 
             ((CAST(PARSENAME(HostAddress, 4) AS BIGINT)*256*256*256) + 
             (CAST(PARSENAME(HostAddress, 3) AS INT)*256*256)
              + (CAST(PARSENAME(HostAddress, 2) AS INT)*256) 
              + CAST(PARSENAME(HostAddress, 1) AS INT))
             BETWEEN  [ip-to-country].BegingIP and [ip-to-country].EndIP) AS CountryName
     FROM PersonTBL
)
SELECT  COUNT(HostAddress) AS TotalNo, 
        CountryName
FROM CTE
GROUP BY CountryName

答案 1 :(得分:2)

在SQL Server中,不能在group by子句中使用列别名。这是另一种选择:

with cte as (
     SELECT HostAddress,
            (select [ip-to-country].CountryName
             from [ip-to-country]
             where ((CAST(PARSENAME(HostAddress, 4) AS Bigint)*256*256*256) + 
                    (CAST(PARSENAME(HostAddress, 3) AS INT)*256*256) +
                    (CAST(PARSENAME(HostAddress, 2) AS INT)*256) +
                     CAST(PARSENAME(HostAddress, 1) AS INT)
                   ) between  [ip-to-country].BegingIP and [ip-to-country].EndIP
            ) as CountryName
     FROM PersonTBL
    )
select count(HostAddress) as TotalNo, CountryName
from cte
Group By CountryName;

答案 2 :(得分:-3)

你错过了一个)。尝试:

SELECT  Count(HostAddress) as TotalNo,
 (select [ip-to-country].CountryName from [ip-to-country] where 
 ((CAST(PARSENAME(HostAddress, 4) AS Bigint)*256*256*256) + 
(CAST(PARSENAME(HostAddress, 3) AS INT)*256*256)
 + (CAST(PARSENAME(HostAddress, 2) AS INT)*256) 
 + CAST(PARSENAME(HostAddress, 1) AS INT))
between  [ip-to-country].BegingIP and [ip-to-country].EndIP) as CountryName
)
 FROM PersonTBL 
 Group By 
 CountryName

我没有你的桌子所以我不确定它是否会起作用,但它更有可能!