Bạn có thể sử dụng bí danh trong mệnh đề WHERE trong mysql không?


121

Tôi cần sử dụng một bí danh trong mệnh đề WHERE, nhưng Nó liên tục cho tôi biết rằng nó là một cột không xác định. Có cách nào để giải quyết vấn đề này không? Tôi cần chọn các bản ghi có xếp hạng cao hơn x. Xếp hạng được tính như bí danh sau:

sum(reviews.rev_rating)/count(reviews.rev_id) as avg_rating

Câu trả lời:


229

Bạn có thể sử dụng mệnh đề HAVING, mệnh đề này có thể thấy các bí danh, ví dụ:

 HAVING avg_rating>5

nhưng trong mệnh đề where bạn cần lặp lại biểu thức của mình, ví dụ:

 WHERE (sum(reviews.rev_rating)/count(reviews.rev_id))>5

NHƯNG! Không phải tất cả các biểu thức đều được phép - sử dụng một hàm tổng hợp như SUM sẽ không hoạt động, trong trường hợp đó, bạn sẽ cần sử dụng mệnh đề HAVING.

Từ MySQL Manual :

Không được phép tham chiếu đến bí danh cột trong mệnh đề WHERE, vì giá trị cột có thể chưa được xác định khi mệnh đề WHERE được thực thi. Xem Phần B.1.5.4, “Sự cố với Bí danh Cột” .


1
Nếu tôi lặp lại các biểu hiện, nó nói với tôi: "sử dụng không hợp lệ của chức năng nhóm"

3
Đã reworded để làm cho nó chức năng aggregrating rõ ràng không allowedd
Paul Dixon

Giải thích tốt, đặc biệt. các "nhưng trong một mệnh đề where ... lặp lại .." phần
th3an0maly

4
Đây là một câu trả lời tốt, nhưng hãy xem xét các tác động về hiệu suất vì HAVINGthực thi sau khi dữ liệu được tìm nạp và WHEREthực thi trước đó.
StockB

Bạn không thể sử dụng các hàm tổng hợp trong mệnh đề WHERE. Mệnh đề WHERE chỉ lọc từng hàng một, không lọc toàn bộ nhóm.
Bill Karwin

33

Không cần thiết nếu điều này hoạt động trong mysql nhưng sử dụng sqlserver, bạn cũng có thể chỉ cần bọc nó như sau:

select * from (
  -- your original query
  select .. sum(reviews.rev_rating)/count(reviews.rev_id) as avg_rating 
  from ...) Foo
where Foo.avg_rating ...

6

Câu hỏi này khá cũ và một câu trả lời đã nhận được 160 phiếu bầu ...

Tuy nhiên, tôi sẽ làm rõ điều này: Câu hỏi thực sự không phải là liệu các tên bí danh có thể được sử dụng trong WHEREmệnh đề hay không.

sum(reviews.rev_rating) / count(reviews.rev_id) as avg_rating

là một tập hợp. Trong WHEREmệnh đề, chúng tôi hạn chế các bản ghi mà chúng tôi muốn từ các bảng bằng cách xem xét các giá trị của chúng. sum(reviews.rev_rating)count(reviews.rev_id), tuy nhiên, không phải là các giá trị chúng tôi tìm thấy trong một bản ghi; chúng là những giá trị mà chúng tôi chỉ nhận được sau khi tổng hợp các bản ghi.

Vì vậy, WHERElà không phù hợp. Chúng tôi cần HAVING, vì chúng tôi muốn hạn chế các hàng kết quả sau khi tổng hợp. Nó không thể được

WHERE avg_rating > 10

cũng không

WHERE sum(reviews.rev_rating) / count(reviews.rev_id) > 10

vì thế.

HAVING sum(reviews.rev_rating) / count(reviews.rev_id) > 10

mặt khác là có thể và tuân thủ tiêu chuẩn SQL. Trong khi

HAVING avg_rating > 10

chỉ có thể trong MySQL. Nó không phải là SQL hợp lệ theo tiêu chuẩn, vì SELECTmệnh đề được cho là sẽ được thực thi sau đó HAVING. Từ tài liệu MySQL:

Một phần mở rộng MySQL khác cho SQL chuẩn cho phép các tham chiếu trong mệnh đề HAVING đến các biểu thức bí danh trong danh sách chọn.

Phần mở rộng MySQL cho phép sử dụng bí danh trong mệnh đề HAVING cho cột tổng hợp

https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html


0

Nếu truy vấn của bạn là tĩnh, bạn có thể xác định nó như một dạng xem thì bạn có thể sử dụng bí danh đó trong mệnh đề where trong khi truy vấn dạng xem.


0
SELECT * FROM (SELECT customer_Id AS 'custId', gender, age FROM customer
    WHERE  gender = 'F') AS c
WHERE c.custId = 100;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.