2014-01-23 37 views
2

我有兩個表:SQL服務器:集團通過選擇statment給錯誤

  • PersonTBL表:包含一個存儲人
  • 的IP地址
  • ip-to-country表中的列HostAddress:包括IP號碼與範圍國家

我試圖計算每個國家的人,但是我收到一個錯誤:

Invalid column name '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 

但我收到另一個錯誤:

Cannot use an aggregate or a subquery in an expression used for the group by list of a GROUP BY clause.

任何一個可以通過國家幫助我組的用戶?

回答

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服務器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 
-3

你錯過了a)。嘗試:

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 

我還沒有你的表,所以我不知道它會工作,但它更可能!

+3

此次榮獲」噸工作,你不能像'GROUP BY'那樣使用列別名 – Lamak

+0

哦,是的,對不起。把插入的)放在「as Country」之前。 –

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;