在WHERE语句中使用子查询的别名

时间:2012-07-26 21:25:17

标签: sql sql-server sql-server-2008 subquery

我正在尝试使用在SELECT中创建的别名,但在WHERE语句中。我知道它不起作用,我只是在另一个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;

但我不想重复那个子查询。而且我很确定它的性能不是很好,所以这就是我在这里要求更好的解决方案的原因。

谢谢!

6 个答案:

答案 0 :(得分:12)

尝试使用派生表。

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; 

答案 1 :(得分:1)

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;

答案 2 :(得分:1)

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; 

这应该也可以很快起作用

答案 3 :(得分:0)

您可以尝试在标准SQL中使用 WITH 子句。

WITH Subquery AS
(
    Your Code
)

然后你的代码

SELECT ....
Subquery As sq
From Patients p
WHERE(subquery)>60

答案 4 :(得分:0)

使用公用表表达式:

;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

答案 5 :(得分:-1)

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