我在僵局中。
当我运行以下查询时,它可以工作:
select DISTINCT l.Seating_Capacity - (select count(*)
from tblTrainings t1, tbllocations l
where l.locationId = t1.LocationId) as
availableSeats
from tblTrainings t1, tbllocations l
where l.locationId = t1.LocationId
但是,我们想添加一个CASE语句,当Seating_Capacity - 如上所示的总计数= 0时,显示'FULL'消息。
否则,显示剩余号码。
以下是该查询:
select DISTINCT case when l.Seating_Capacity - (select count(*)
from tblTrainings t1, tbllocations l
where l.locationId = t1.LocationId) = 0 then 'full' else STR(Seating_Capacity) end)
availableSeats
from tblTrainings t1, tbllocations l
where l.locationId = t1.LocationId
我收到'不正确的语法''''接近'结束'
我也收到一条错误,内部Seating_Capacity是无效的列名。
非常感谢您的协助。
我一定是在梦乡,因为我认为它在测试过程中起作用了。
现在,该应用程序已启用,但无效。
提前多多感谢
select DISTINCT l.LocationId,c.courseId, c.coursename, l.Seating_Capacity - (select count(*)
from tblTrainings t1
where l.locationId = t1.LocationId and c.courseId = t1.courseId) as
availableSeats,d.dateid,d.trainingDates,d.trainingtime,c.CourseDescription,
i.instructorName,l.location,l.seating_capacity
from tblLocations l
Inner Join tblCourses c on l.locationId = c.locationId
left join tblTrainings t on l.locationId = t.LocationId and c.courseId = t.courseId
Inner Join tblTrainingDates d on c.dateid=d.dateid
Inner Join tblCourseInstructor ic on c.courseId = ic.CourseId
Inner Join tblInstructors i on ic.instructorId = i.instructorId
WHERE CONVERT(VARCHAR(10), d.trainingDates, 101) >= CONVERT(VARCHAR(10), GETDATE(), 101)
答案 0 :(得分:3)
为避免重复表达,您可以使用WITH
clause来简化查询:
WITH (
-- Start with your query that already works
SELECT DISTINCT l.Seating_Capacity - (select count(*)
from tblTrainings t1, tbllocations l
where l.locationId = t1.LocationId) AS availableSeats
FROM tblTrainings t1, tbllocations l
WHERE l.locationId = t1.LocationId
) AS source
SELECT
-- Add a CASE statement on top of it
CASE WHEN availableSeats = 0 THEN 'Full'
ELSE STR(availableSeats)
END AS availableSeats
FROM source
答案 1 :(得分:2)
在您的案例陈述结尾处有一个额外的)
删除它。
0 then 'full' else STR(Seating_Capacity) end)
^^^
Seating_Capacity
尝试使用{al} {/ p>等表别名访问它
答案 2 :(得分:0)
我认为你的子查询使查询复杂化了。据我所知,以下内容应该可以根据需要使用:
SELECT AvailableSeats = CASE WHEN l.Seating_Capacity - COUNT(*) = 0 THEN 'Full'
ELSE STR(l.Seating_Capacity - COUNT(*))
END
FROM tblTrainings t1
INNER JOIN tblLocations l
ON l.LocationID = t1.LocationID
GROUP BY l.Seating_Capacity;
我已将其他人更改为STR(l.Seating_Capacity - COUNT(*))
,因为我认为您想知道剩下的座位,而不仅仅是容量?如果我误解了要求,只需将其更改为STR(l.Seating_Capacity)
。
我还将ANSI 89隐式连接切换为ANSI 92显式连接,标准更改超过20年,并且plenty of good reasons可以切换到更新的语法。但为了完整起见,上述查询的ANSI 89版本将是:
SELECT AvailableSeats = CASE WHEN l.Seating_Capacity - COUNT(*) = 0 THEN 'Full'
ELSE STR(l.Seating_Capacity - COUNT(*))
END
FROM tblTrainings t1, tblLocations l
WHERE l.LocationID = t1.LocationID
GROUP BY l.Seating_Capacity;
修改强>
要调整完整查询,您只需使用已连接的子查询替换select中的子查询:
SELECT l.LocationId,
c.courseId,
c.coursename,
CASE WHEN l.Seating_Capacity - t.SeatsTaken = 0 THEN 'Full'
ELSE STR(l.Seating_Capacity - t.SeatsTaken)
END AS availableSeats,
d.dateid,
d.trainingDates,
d.trainingtime,
c.CourseDescription,
i.instructorName,
l.location,
l.seating_capacity
FROM tblLocations l
INNER JOIN tblCourses c
ON l.locationId = c.locationId
LEFT JOIN
( SELECT t.LocationID, t.CourseID, SeatsTaken = COUNT(*)
FROM tblTrainings t
GROUP BY t.LocationID, t.CourseID
) t
ON l.locationId = t.LocationId
AND c.courseId = t.courseId
INNER JOIN tblTrainingDates d
ON c.dateid=d.dateid
INNER JOIN tblCourseInstructor ic
ON c.courseId = ic.CourseId
INNER JOIN tblInstructors i
ON ic.instructorId = i.instructorId
WHERE d.trainingDates >= CAST(GETDATE() AS DATE);
JOIN倾向于比相关子查询更好地优化(尽管有时优化器可以确定JOIN会起作用),这也意味着您可以多次引用结果(SeatsTaken
)而无需重新评估子查询
此外,通过将计数移至子查询,并将联接移至tblTrainings
,我认为您无需DISTINCT
来提高性能。
最后我改变了这一行:
WHERE CONVERT(VARCHAR(10), d.trainingDates, 101) >= CONVERT(VARCHAR(10), GETDATE(), 101)
要
WHERE d.trainingDates >= CAST(GETDATE() AS DATE);
我不知道你是否这样做,但如果你有一个关于d.TrainingDates的索引,那么通过将其转换为varchar来与今天进行比较,你将删除优化器使用这个索引的能力,因为你只是说今天午夜>=
,无需在d.TrainingDates上执行任何转换,您需要做的就是删除GETDATE()的时间部分,这可以通过强制转换为DATE来完成。关于此的更多内容包含in this article(来自Aaron Bertrand的另一个宝石)