SELECT logcount, logUserID, maxlogtm
, DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
WHERE daysdiff > 120
ฉันเข้าใจ
"ชื่อคอลัมน์ไม่ถูกต้อง daysdiff"
Maxlogtm เป็นฟิลด์ datetime มันเป็นสิ่งเล็กน้อยที่ทำให้ฉันบ้า
SELECT logcount, logUserID, maxlogtm
, DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
WHERE daysdiff > 120
ฉันเข้าใจ
"ชื่อคอลัมน์ไม่ถูกต้อง daysdiff"
Maxlogtm เป็นฟิลด์ datetime มันเป็นสิ่งเล็กน้อยที่ทำให้ฉันบ้า
คำตอบ:
SELECT
logcount, logUserID, maxlogtm,
DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
WHERE ( DATEDIFF(day, maxlogtm, GETDATE() > 120)
โดยปกติแล้วคุณไม่สามารถอ้างถึงสมนามฟิลด์ในWHERE
ประโยค (คิดว่าเป็นภาพSELECT
รวมรวมถึงชื่อแทนถูกนำไปใช้หลังจากWHERE
ข้อ)
แต่ดังที่กล่าวไว้ในคำตอบอื่น ๆ คุณสามารถบังคับให้ SQL SELECT
จัดการกับการจัดการก่อนส่วนWHERE
คำสั่ง โดยปกติจะทำด้วยวงเล็บเพื่อบังคับลำดับการดำเนินการทางตรรกะหรือด้วย Common Table Expression (CTE):
วงเล็บ / subselect:
SELECT
*
FROM
(
SELECT
logcount, logUserID, maxlogtm,
DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
) as innerTable
WHERE daysdiff > 120
หรือดูคำตอบของอดัมสำหรับรุ่น CTE ที่เหมือนกัน
HAVING
คำตอบไม่ได้ผลในสภาพแวดล้อม SQL ส่วนใหญ่รวมถึง MS-SQL ที่คำถามนี้เกี่ยวกับ (ใน T-SQL HAVING
ต้องการฟังก์ชันการรวม)
หากคุณต้องการใช้นามแฝงในWHERE
ข้อของคุณคุณต้องล้อมมันในตัวเลือกย่อยหรือ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
วิธีที่มีประสิทธิภาพที่สุดในการทำโดยไม่ต้องทำซ้ำรหัสของคุณคือการใช้HAVINGแทนที่จะเป็นWHERE
SELECT logcount, logUserID, maxlogtm
, DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
HAVING daysdiff > 120
HAVING
ชื่อแทนนั้นไม่ได้มาตรฐาน (ใช้ได้กับ MySQL) โดยเฉพาะฉันคิดว่ามันใช้ไม่ได้กับ 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.
หากคุณไม่ต้องการแสดงรายการคอลัมน์ทั้งหมดของคุณใน CTE วิธีอื่นในการทำเช่นนี้ก็คือการใช้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
วิธีการเกี่ยวกับการใช้แบบสอบถามย่อย (นี้ทำงานให้ฉันใน Mysql)
SELECT * from (SELECT logcount, logUserID, maxlogtm
, DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary) as 'your_alias'
WHERE daysdiff > 120
HAVING ทำงานใน MySQL ตามเอกสาร:
ส่วนคำสั่งHAVINGถูกเพิ่มไปยัง SQL เนื่องจากไม่สามารถใช้คำสำคัญ WHERE กับฟังก์ชันรวมได้
คุณสามารถอ้างถึงนามแฝงคอลัมน์ แต่คุณจำเป็นต้องกำหนดโดยใช้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;
ข้อดี:
WHERE/GROUP BY/ORDER BY
sql-server
และt-sql
:)
มาที่นี่กำลังมองหาบางอย่างที่คล้ายกัน แต่มีกรณีเมื่อและจบลงด้วยการใช้ที่เช่นนี้: WHERE (CASE WHEN COLUMN1=COLUMN2 THEN '1' ELSE '0' END) = 0
บางทีคุณสามารถใช้DATEDIFF
ในWHERE
โดยตรง สิ่งที่ต้องการ:
SELECT logcount, logUserID, maxlogtm
FROM statslogsummary
WHERE (DATEDIFF(day, maxlogtm, GETDATE())) > 120
`daysdiff`
แต่บางทีนามแฝงจะต้องห่อในเห็บ