Sql 我的陈述是错误的。知道我做错了什么吗?
我陷入了困境 当我运行以下查询时,它可以工作:Sql 我的陈述是错误的。知道我做错了什么吗?,sql,sql-server-2008,sql-server-2005,Sql,Sql Server 2008,Sql Server 2005,我陷入了困境 当我运行以下查询时,它可以工作: select DISTINCT l.Seating_Capacity - (select count(*) from tblTrainings t1, tbllocations l where l.locationId = t1.LocationId) as availableSeats
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
然而,我们想添加一个案例说明,当座位容量-总计数如上所示=0时,则显示“满”消息
否则,显示剩余的数字
这是一个问题:
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
我得到了接近“End”的“error syntax near”)
我还得到一个错误,即内部座位容量是无效的列名
非常感谢你的帮助
我一定是在梦境中,因为我认为它在测试中起作用
现在,该应用程序已上线,但无法运行
提前多谢
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 then 'full' else STR(Seating_Capacity) end)
^^^
对于
座位容量
请尝试使用表别名(如l)访问它。座位容量
为避免重复该表达式,可以使用简化查询:
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
我认为您的子查询过于复杂了。据我所知,以下各项应能满足您的需要:
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;
我已将您的else更改为STR(l.seatching_Capacity-COUNT(*),因为我假设您想知道剩余的座位,而不仅仅是容量?如果我误解了要求,只需将其更改为STR(l.座位容量)
我还将您的ANSI 89隐式连接转换为ANSI 92显式连接,标准在20年内发生了变化,并且需要切换到更新的语法。但为了完整性,上述查询的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);
连接往往比相关子查询优化得更好(尽管有时优化者可以确定连接是否有效),这也意味着您可以多次引用结果(seatstake
),而无需重新评估子查询
此外,通过将计数移动到子查询,并删除与tblTrainings
的连接,我认为您不需要使用DISTINCT
,这将提高性能
最后,我改变了这一行:
WHERE CONVERT(VARCHAR(10), d.trainingDates, 101) >= CONVERT(VARCHAR(10), GETDATE(), 101)
到
我不知道你是否知道,但是如果你有一个关于d.TrainingDates的索引,那么通过将其转换为varchar,将其与今天进行比较,你就消除了乐观主义者使用该索引的能力,因为你今天只说
=
午夜,没有必要对d.TrainingDates执行任何转换,您所需要做的就是删除GETDATE()的时间部分,这可以通过强制转换为DATE来完成。在END
关键字之后包含了更多关于这一点的信息(来自)remoce)
。非常激动人心的反应!你们真是太棒了。非常非常感谢你们这么快救了我。我不知道如何奖励这些分数。我想勾选每一个方框。如果有这样做的机会,请各位专家告诉我。它工作得很好。谢谢@Dasbliklight,你的查询很酷,但我无法运行它。这是给各种各样的错误。首先,它与第一个(
。我修复了这个问题,它开始在AS source上出现错误。等等,请原谅。我没有发布完整的代码,因为我认为我可以将我拥有的任何解决方案与我的其余代码集成,但我在做这件事时遇到了问题。我已经发布了上面的整个查询。你能帮助我集成Gareth的解决方案吗很抱歉。感谢上帝,感谢像你这样的人。愿上帝保佑你的耐心和帮助。谢谢你,先生!!!
WHERE d.trainingDates >= CAST(GETDATE() AS DATE);