我正在尝试在 WHERE 语句中使用在 SELECT 中创建的别名。它不起作用,我在另一个 SO 问题中读到了原因。
如何在不重复子查询的情况下完成这项工作?
SELECT p.PatientID, p.PatientType, p.AccountNumber,
p.FirstName + ' ' + p.LastName PatientFullName,
p.CreatedDate, DATEDIFF(hour, p.CreatedDate, GETDATE()) TotalTime,
(SELECT AVG(BGValue)
FROM BloodGlucose
WHERE PatientID = p.PatientID) AvgBG
FROM Patients p
WHERE AvgBG > 60;
这有效:
SELECT p.PatientID, p.PatientType, p.AccountNumber,
p.FirstName + ' ' + p.LastName PatientFullName, p.CreatedDate,
DATEDIFF(hour, p.CreatedDate, GETDATE()) TotalTime,
(SELECT AVG(BGValue) FROM BloodGlucose WHERE PatientID = p.PatientID) AvgBG
FROM Patients p
WHERE (SELECT AVG(BGValue) FROM BloodGlucose WHERE PatientID = p.PatientID) > 60;
但是我不想重复那个子查询。而且我怀疑它的性能很差。
尝试使用派生表。
SELECT p.PatientID, p.PatientType, p.AccountNumber,
p.FirstName + ' ' + p.LastName PatientFullName,
p.CreatedDate, DATEDIFF(hour, p.CreatedDate, GETDATE()) TotalTime,
bg.AvgBG
FROM Patients p
JOIN (SELECT PatientID, AVG(BGValue) AvgBG
FROM BloodGlucose group by PatientID) BG
ON BG.PatientID = p.PatientID
WHERE AvgBG > 60;
派生表按集合工作,相关子查询逐行工作,这就是我的速度更快的原因。
WHERE 子句中的别名只能来自FROM 子句。这是重写查询的一种方法:
SELECT p.PatientID, p.PatientType, p.AccountNumber,
p.FirstName + ' ' + p.LastName as PatientFullName, p.CreatedDate,
DATEDIFF(hour, p.CreatedDate, GETDATE()) TotalTime,
av.AvgBG
FROM Patients p join
(SELECT PatientId, AVG(BGValue) as AvgBG
FROM BloodGlucose
group by PatientID
) av
on p.PatientId = av.PatientId
WHERE av.AvgBG > 60;
SELECT p.PatientID, p.PatientType, p.AccountNumber, p.FirstName + ' ' + p.LastName PatientFullName, p.CreatedDate, DATEDIFF(hour, p.CreatedDate, GETDATE()) TotalTime, bg.AvgBG
FROM Patients p
outer apply (SELECT PatientID, AVG(BGValue) AvgBG
FROM BloodGlucose where PatientID = p.PatientID
group by PatientID ) BG
WHERE AvgBG > 60;
这也应该工作得很快
SELECT p.PatientID, p.PatientType, p.AccountNumber, p.FirstName p.LastName PatientFullName, p.CreatedDate,
DATEDIFF(hour, p.CreatedDate, GETDATE()) TotalTime, a.AvgBG
FROM Patients p,
(SELECT PatientID, AVG(BGValue) AvgBG
FROM BloodGlucose
group by PatientID
having AVG(BGValue) > 60) a
where p.PatientID = a.PatientID
您可以尝试在标准 SQL 中使用 WITH 子句。
WITH Subquery AS
(
Your Code
)
然后是你的代码
SELECT ....
Subquery As sq
From Patients p
WHERE(subquery)>60
使用通用表表达式:
;WITH CTE (PatientID, PatientType, AccountNumber, PatientFullName, CreatedDate, TotalTime, AvgBG) AS (
SELECT p.PatientID, p.PatientType, p.AccountNumber, p.FirstName + ' ' + p.LastName PatientFullName, p.CreatedDate,
DATEDIFF(hour, p.CreatedDate, GETDATE()) TotalTime,
(SELECT AVG(BGValue) FROM BloodGlucose WHERE PatientID = p.PatientID) AvgBG
FROM Patients p
)
SELECT PatientID, PatientType, AccountNumber, PatientFullName, CreatedDate, TotalTime, AvgBG
FROM CTE
WHERE AvgBG > 60