使用视图

时间:2016-05-05 04:36:29

标签: sql-server

这是我想要做的简化示例。假设有一个名为承包商的表,如下所示:

name | paid_adjustment_amount | adj_date
Bob  | 1000                   | 4/7/2016
Mary | 2000                   | 4/8/2016
Bill | 5000                   | 4/8/2016
Mary | 4000                   | 4/10/2016
Bill | (1000)                 | 4/12/2016
Ann  | 3000                   | 4/30/2016

有一个承包商表的视图,我们称之为v_sum,这只是按名称分组的paid_adustment_amount的SUM。所以它看起来像这样:

name | total_paid_amount
Bob  | 1000
Mary | 6000
Bill | 4000
Ann  | 3000

最后,还有另一个名为to_date_payment的表,如下所示:

name | paid_to_date_amount
Bob  | 1000
Mary | 8000
Bill | 3000
Ann  | 3000
Joe  | 4000      

我想将to_date_payment表中的信息与v_sum视图进行比较,并在承包商表中插入一个新行以显示调整。像这样:

INSERT INTO contractor
SELECT to_date_payment.name, 
    to_date_payment.paid_to_date_amount - v_sum.total_paid_amount,
    GETDATE()
FROM to_date_payment
LEFT JOIN v_sum ON to_date_payment.name = v_sum.name
WHERE to_date_payment.paid_to_date_amount - v_sum.total_paid_amount <> 0
    OR v_sum.name IS NULL

使用视图是否有任何问题?我的理解,如果我错了,请纠正我,是视图只是查询的结果集。而且,由于我在插入新记录的表格中,我担心可能存在数据完整性问题。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

为了完全理解你在做什么,你还应该提供v_sum的定义。一般来说,视图可能会提供一些优势,尤其是在索引时。可以找到更多详细信息herehere

简单地使用视图不会带来性能优势,但它们非常适合提供表格抽象。

在您的特定情况下,我认为在使用视图加入时没有任何问题,但我担心与以下相关的潜在问题:

1)使用VARCHAR而不是整数 JOIN - ON to_date_payment.name = v_sum.name - 如果可能,尝试JOIN对整数(ids或外键ID)值,如它更快(应用于整数列的索引将具有更小的键,比较稍快)。

2)查询中的OR - 通常会导致性能问题。要尝试的一件事是像这样更改SELECT:

SELECT to_date_payment.name, 
    to_date_payment.paid_to_date_amount - v_sum.total_paid_amount,
    GETDATE()
FROM to_date_payment
JOIN v_sum ON to_date_payment.name = v_sum.name
WHERE to_date_payment.paid_to_date_amount - v_sum.total_paid_amount <> 0

UNION ALL

SELECT to_date_payment.name, 
    to_date_payment.paid_to_date_amount,    -- or NULL if this is really intended
    GETDATE()
FROM to_date_payment
-- NOT EXISTS is usually faster than LEFT JOIN ... IS NULL
WHERE NOT EXISTS (SELECT 1 FROM v_sum V WHERE V.name = to_date_payment.name)

3)可能出现意外结果 - 默认情况下,涉及NULL的算法返回NULL。当v_sum中没有匹配项时,v_sum.total_paid_amount为NULL,而to_date_payment.paid_to_date_amount - v_sum.total_paid_amount将计算为NULL。它是否正确?也许是to_date_payment.paid_to_date_amount - ISNULL(v_sum.total_paid_amount, 0)