SELECT logcount, logUserID, maxlogtm
, DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
WHERE daysdiff > 120
tôi có
"ngày tên cột không hợp lệ".
Maxlogtm là một trường datetime. Đó là những thứ nhỏ khiến tôi phát điên.
SELECT logcount, logUserID, maxlogtm
, DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
WHERE daysdiff > 120
tôi có
"ngày tên cột không hợp lệ".
Maxlogtm là một trường datetime. Đó là những thứ nhỏ khiến tôi phát điên.
Câu trả lời:
SELECT
logcount, logUserID, maxlogtm,
DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
WHERE ( DATEDIFF(day, maxlogtm, GETDATE() > 120)
Thông thường bạn không thể tham khảo các bí danh trường trong WHERE
mệnh đề. (Hãy nghĩ về nó như toàn bộ SELECT
bao gồm các bí danh, được áp dụng sau WHERE
mệnh đề.)
Nhưng, như đã đề cập trong các câu trả lời khác, bạn có thể buộc SQL xử lý SELECT
để được xử lý trước WHERE
mệnh đề. Điều này thường được thực hiện với dấu ngoặc đơn để buộc thứ tự hoạt động hợp lý hoặc với Biểu thức bảng chung (CTE):
Dấu ngoặc đơn / Đăng ký:
SELECT
*
FROM
(
SELECT
logcount, logUserID, maxlogtm,
DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
) as innerTable
WHERE daysdiff > 120
Hoặc xem câu trả lời của Adam cho phiên bản CTE giống nhau.
HAVING
trả lời không hoạt động trong hầu hết các môi trường SQL, bao gồm cả MS-SQL mà câu hỏi này đề cập đến. (Trong T-SQL, HAVING
yêu cầu hàm tổng hợp.)
Nếu bạn muốn sử dụng bí danh trong WHERE
mệnh đề của mình , bạn cần phải bọc nó trong phần chọn phụ hoặc CTE :
WITH LogDateDiff AS
(
SELECT logcount, logUserID, maxlogtm
, DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
)
SELECT logCount, logUserId, maxlogtm, daysdiff
FROM LogDateDiff
WHERE daysdiff > 120
Cách hiệu quả nhất để làm điều đó mà không lặp lại mã của bạn là sử dụng HAVING thay vì WHERE
SELECT logcount, logUserID, maxlogtm
, DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
HAVING daysdiff > 120
HAVING
trên các bí danh là không chuẩn (mặc dù nó hoạt động trên MySQL). Cụ thể, tôi nghĩ rằng nó không hoạt động với SQL Server.
[S0001][207] Invalid column name 'daysdiff'
[S0001][8121] Column 'day' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.
Nếu bạn không muốn liệt kê tất cả các cột trong CTE, một cách khác để làm điều này sẽ là sử dụng outer apply
:
select
s.logcount, s.logUserID, s.maxlogtm,
a.daysdiff
from statslogsummary as s
outer apply (select datediff(day, s.maxlogtm, getdate()) as daysdiff) as a
where a.daysdiff > 120
Làm thế nào về việc sử dụng một truy vấn con (điều này làm việc cho tôi trong Mysql)?
SELECT * from (SELECT logcount, logUserID, maxlogtm
, DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary) as 'your_alias'
WHERE daysdiff > 120
Bạn có thể tham khảo bí danh cột nhưng bạn cần xác định nó bằng cách sử dụng CROSS/OUTER APPLY
:
SELECT s.logcount, s.logUserID, s.maxlogtm, c.daysdiff
FROM statslogsummary s
CROSS APPLY (SELECT DATEDIFF(day, s.maxlogtm, GETDATE()) AS daysdiff) c
WHERE c.daysdiff > 120;
Ưu điểm:
WHERE/GROUP BY/ORDER BY
sql-server
và t-sql
:)
Đến đây tìm kiếm một cái gì đó tương tự như vậy, nhưng với một trường hợp xảy ra và kết thúc bằng cách sử dụng nơi như thế này: WHERE (CASE WHEN COLUMN1=COLUMN2 THEN '1' ELSE '0' END) = 0
có lẽ bạn có thể sử dụng DATEDIFF
trong WHERE
trực tiếp. Cái gì đó như:
SELECT logcount, logUserID, maxlogtm
FROM statslogsummary
WHERE (DATEDIFF(day, maxlogtm, GETDATE())) > 120
`daysdiff`
.