Sql 使用多个表格计算总价格

Sql 使用多个表格计算总价格,sql,sql-server,Sql,Sql Server,这是一个linux 18.04。我打算在VS代码中执行SQL代码,以计算我的客人应该支付多少住宿费用。我有三张桌子——预订、房间和发票 DECLARE @day NUMERIC, @price NUMERIC, @total NUMERIC, @resID NUMERIC SELECT @resID = resID FROM Reservation GROUP BY resID; WHILE @resID <= 10 BEGIN SELECT @day = DATEDIFF(day

这是一个linux 18.04。我打算在VS代码中执行SQL代码,以计算我的客人应该支付多少住宿费用。我有三张桌子——预订、房间和发票

DECLARE @day NUMERIC, @price NUMERIC, @total NUMERIC, @resID NUMERIC
SELECT @resID = resID FROM Reservation GROUP BY resID;
WHILE @resID <= 10
BEGIN
    SELECT @day = DATEDIFF(day, departure_date, arrival_date) FROM Reservation
    SELECT @price = price_per_night FROM Room
    SELECT @total = @day * @price;
    UPDATE Invoice SET overall_price = @total;
SET @resID = @resID+1
END

SELECT * FROM Invoice;
声明@day NUMERIC、@price NUMERIC、@total NUMERIC、@resID NUMERIC
按resID从预订组中选择@resID=resID;

而@resID我们看到您有很多东西需要学习。所有现有代码都可以替换为2条语句—更新和选择。您可以从循环和单行的角度进行思考,这是传统编程语言的典型特征。在tsql中,您需要从集合的角度进行思考

您应该执行的基本伪代码示例如下:

update dbo.Invoice set overall_price = 
    (select price_per_night * datediff(day, arrival_date, departure_date) from ....)
where ... ;

select ... from dbo.Invoice order by ...; 
这不是有效的代码。它需要在许多方面进行调整。但请注意,发票与客户和房间之间必须存在关系。这就是为什么需要DDL。正如我所评论的,你做了很多假设,这些假设在现实生活中根本是无效的。也许这是一个简单的训练练习——你在提问时也应该提到这一点。这样做可以避免大量描述潜在陷阱和复杂情况的额外工作,并避免讨论您不需要的复杂性

还有一些额外的想法。“总价格”一词具有误导性。您的客户必须支付最终或全部金额。正如我前面提到的,这通常不仅仅是房间的费用。你是否考虑过当顾客使用多个房间时会发生什么?您的目标是为每个房间分别开具发票吗?不同的房间可以有不同的价格。你考虑过税收和其他费用吗?最后,您确实只想更新处于某些状态的发票,这些状态表明发票尚未“完成”。您不想更新旧发票,尤其是付费发票。所以这里还有很多复杂的地方你还没有考虑。 一条特定于代码的注释。你有这个:

SELECT @resID = resID FROM Reservation GROUP BY resID;
想一想这是怎么回事。显然,您可以而且确实期望它生成许多行。那么你认为它给你的变量分配了什么值呢?语言能保证你期望的价值吗?事实并非如此。分配的值将是生成的集合中的一个,但不能保证分配最低的值。这是一个常见且错误的假设。那么,如何在tsql中正确表达您的目标呢

set @resID = (select min(resID) from dbo.Reservation); 
注意一些您需要开始使用的最佳实践。首先,终止你的陈述。最终它将是必需的。接下来,使用SET而不是SELECT来分配变量。这有很大的区别。最后,对表进行模式限定。所有这些都是最佳实践,您应该花一些时间学习它们


还有最后一个想法。如果你真的需要一个循环,那么就使用光标。一般来说,在高效的tsql代码中很少需要循环(和游标)。如果您发现自己认为代码中需要一个循环,那么是时候退一步,重新设想您的问题和解决方案的最佳路径了

没有明确的问题被问到,样本数据和预期的输出都丢失了重新开始-这次开始考虑您的代码。声明变量或列时,不要依赖默认长度、精度和比例。这里的“数值”是指“数值(18,0)”。如果您确实想使用该数据类型(可疑),那么您应该这样定义它。你会发现生活很混乱。并不是每个酒店的客人都有预订。那你怎么办?有时价格每天都在变化。我能订一间单人房吗(出发和到达是同一天)?这种情况经常发生。还有其他费用。食物、酒吧、损坏、丢失的物品等。假设您有一些客人,您应该使用WHERE子句仅选择并更新该特定客人的行。此外,update语句可以更新多行(不同行的多个值),并且您正在使用声明的变量(单个值),鉴于问题的意图,该变量是不正确的。