2010-01-15 25 views
46

Tôi đã tự hỏi tại sao tôi không thể sử dụng bí danh trong một số (*) và tham khảo nó trong mệnh đề có. Ví dụ:Tại sao tôi không thể sử dụng bí danh trong cột đếm (*) "và tham chiếu nó trong một mệnh đề có?

select Store_id as StoreId, count(*) as _count 
    from StoreProduct 
    group by Store_id 
     having _count > 0 

Sẽ không hoạt động .. Nhưng nó hoạt động nếu tôi xóa _count và sử dụng số (*) thay thế.

Trả lời

75

Xem document referenced bởi CodeByMoonlight trong một answer-your recent question.

Mệnh đề HAVING được đánh giá trước SELECT - vì vậy máy chủ chưa biết về bí danh đó.

  1. Đầu tiên là sản phẩm của tất cả các bảng trong từ khoản được hình thành.
  2. Giá trị trong đó sau đó được đánh giá để loại bỏ các hàng không đáp ứng điều kiện tìm kiếm.
  3. Tiếp theo, các hàng được nhóm theo các cột trong nhóm theo mệnh đề.
  4. Sau đó, Nhóm không đáp ứng điều kiện tìm kiếm trong các điều khoản có điều khoản sẽ bị loại bỏ.
  5. Tiếp theo, các biểu thức trong danh sách đích chọn được đánh giá là .
  6. Nếu riêng biệt từ khóa hiện tại trong mệnh đề chọn, các hàng trùng lặp hiện bị loại bỏ.
  7. Các công đoàn được thực hiện sau mỗi lần chọn phụ được đánh giá.
  8. Cuối cùng, các hàng kết quả được sắp xếp theo các cột được chỉ định trong yêu cầu theo mệnh đề.
+5

Tôi muốn thêm rằng thứ tự của đánh giá là một khái niệm logic trong SQL. Trong thực tế, trình tối ưu hóa truy vấn có thể chọn một thứ tự hoạt động khác, miễn là các kết quả giống như nếu thứ tự logic đã được theo sau. –

+1

Về cơ bản, bí danh được xác định trong mệnh đề chọn sẽ có hai cách sử dụng: 1) Đặt tên cho cột 2) Sắp xếp –

+2

http://blog.sqlauthority.com/2009/04/06/sql-server-logical-query-processing-phases -order-of-statement-execution/không thực sự là câu hỏi trong tầm tay nhưng anh ta có một danh sách tốt về thứ tự sql thực hiện. Chắc chắn có một danh sách chính thức hơn ở đâu đó. 1. TỪ 2. ON 3. OUTER 4. WHERE 5. GROUP BY 6. CUBE | ROLLUP 7. HAVING 8. CHỌN 9. DISTINCT 10 ORDER BY 11. TOP – JKG

2

Bạn có thể sử dụng bí danh cho đếm trong mệnh đề select, bạn chỉ có thể sử dụng nó trong việc tuyên bố, vì vậy đây sẽ làm việc

select Store_id as StoreId, count(*) as _count 
    from StoreProduct 
    group by Store_id 
     having count(*) > 0 
-1

Có lẽ vì đó là cách sql định nghĩa các không gian tên. lấy, ví dụ:

select a as b, b as a 
    from table 
    where b = '5' 
order by a 

a và b là gì? Các nhà thiết kế vừa chọn để làm cho các bí danh chỉ xuất hiện trên "bên ngoài" của truy vấn.

+0

Các bí danh có sẵn trong mệnh đề 'order by'. Trong ví dụ của bạn, kết quả sẽ được sắp xếp theo 'table.b' được đặt tên là' a'. Hãy thử 'chọn 1 làm đơn hàng bằng'. Điều đó sẽ hợp lệ. Điều này là do thứ tự logic của việc đánh giá, 'order by' xuất hiện sau khi được chọn và có thể thấy các bí danh. –

0

Bạn có thể sử dụng bí danh cho tập hợp trong SQL, nhưng đó chỉ là để hiển thị bí danh trong tiêu đề kết quả. Nhưng khi bạn muốn có một điều kiện với hàm tổng hợp trong việc có bạn vẫn cần phải sử dụng tổng hợp vì nó đánh giá hàm và không phải là tên.

9

Điều khoản select là mệnh đề cuối cùng được thực hiện một cách hợp lý, ngoại trừ order by. Mệnh đề having xảy ra trước khi được chọn, vì vậy các bí danh chưa có sẵn.

Nếu bạn thực sự muốn sử dụng một bí danh, không phải là tôi muốn khuyên bạn nên làm điều này, một cái nhìn trực tuyến có thể được sử dụng để làm các bí danh có sẵn:

select StoreId, _count 
from (select Store_id as StoreId, count(*) as _count 
    from StoreProduct 
    group by Store_id) T 
where _count > 0 

Hoặc trong SQL Server 2005 trở lên , CTE:

; with T as (select Store_id as StoreId, count(*) as _count 
    from StoreProduct 
    group by Store_id) 
select StoreId, _count 
from T 
where _count > 0 
0

Bí danh cho tên trường chỉ để đặt tên cho các cột trong kết quả, chúng không bao giờ được sử dụng trong truy vấn. Bạn không thể làm như thế này hoặc là:

select Store_id as Asdf 
from StoreProduct 
where Asdf = 42 

Tuy nhiên, bạn có thể yên tâm sử dụng count(*) ở cả hai nơi, và cơ sở dữ liệu sẽ nhận ra rằng đó là giá trị như nhau, vì vậy nó sẽ không được tính hai lần.

0

Trong Hive 0.11.0 trở lên, cột có thể được chỉ định theo vị trí nếu hive.groupby.orderby.position.alias được đặt thành true.

set hive.groupby.orderby.position.alias=true; 
select Store_id as StoreId, count(*) as _count 
from StoreProduct 
group by 1 

Tôi không hiểu mục đích truy vấn của bạn. Với ngữ cảnh của truy vấn bạn đã đăng, điều kiện của bạn là không cần thiết vì các mục không tồn tại, i. e. đếm 0, sẽ không bao giờ là kết quả từ một truy vấn ...

0

Đây là đóng góp của tôi (dựa trên mã được đăng ở đây):

select * from (
    SELECT Store_id as StoreId, Count(*) as StoreCount 
    FROM StoreProduct 
    group by Store_id 
) data 
where data.StoreCount > 0