【问题标题】:SQL Sum - Then Join - Then CommentSQL Sum - 然后加入 - 然后注释
【发布时间】:2022-01-15 13:23:42
【问题描述】:

我在将所有这些整合在一起时遇到了一些问题。

我正在使用 Microsoft SQL Server。

我从 3 张桌子开始。

表 #1 - 人员

PersonId Name
1 Doug
2 Mary
3 Mike
4 Tim
5 Hank

表 #2 - FoodTransaction

FoodTransactionId PersonId Cost
1 1 50
2 1 80
3 2 15
4 3 25
5 3 30

表 #3 - EntertainmentTransaction

EntertainmentTransactionId PersonId Cost
1 2 10
2 2 80
3 3 15
4 4 25
5 4 45
6 4 30

从这里开始,我的目标是制作一个汇总表或视图,包括每个人以及按交易类型划分的交易总和。

为了制作下面的视图,我确实选择了一系列子选择。

  • 我从 Person 表和 FoodTransaction 表之间的完全外部联接开始。我创建了一个新字段 sum(FoodTransaction.Cost) 作为 FoodTotal。

  • 然后我在这些结果和 EntertainmentTransaction 表之间进行左连接,在该表中我创建了一个新字段 sum(EntertainmentTransaction.Cost) 作为 EntertainmentTotal。

  • 然后我添加一个 where 子句,说明 FoodTotal 不为 null 或 EntertainmentTotal 不为 null。这个 where 子句从 Person 表中删除所有在任一表上都没有事务的条目。

我已经根据上述条件成功创建了下表。

查看 #1 - 交易摘要

PersonId FoodTotal EntertainmentTotal
1 130
2 15 90
3 55 15
4 100

我的最后一个障碍在下面。我有一个可编辑的评论表,我想加入到视图中。

表 #4 - 注释

CommentId PersonId Comment
1 1 Here's a comment.
2 2 This is another comment.
3 3 How about this comment?
4 4 I like to comment.
5 5

下面的 View 是将 Comment 表连接回 View #1 的结果

查看 #2 - TransactionSummaryComment

PersonId FoodTotal EntertainmentTotal Comment
1 130 Here's a comment.
2 15 90 This is another comment.
3 55 15 How about this comment?
4 100 I like to comment.

这一切都有效。目标是显示此视图并允许用户编辑评论字段。

问题是,如果我从 View #2 中编辑其中一个 cmets,我会收到以下错误:

“无法更新视图或函数,因为它包含聚合、DISTINCT 或 GROUP BY 子句、PIVOT 或 UNPIVOT 运算符。”

这让我认为,由于创建了聚合字段,我正在做的事情不会像这样工作。

我想一定有一种方法可以达到与我尝试过的方法不同的预期结果。

任何关于实现这一目标的更有效方式的想法或建议将不胜感激。

【问题讨论】:

  • 您可以创建两个视图,第一个聚合,第二个将第一个视图与 cmets..然后 cmetstext 列在第二个视图上可更新..dbfiddle.uk/…
  • ..或将聚合放在视图中的派生/子查询中。dbfiddle.uk/…

标签: sql sql-server join view aggregate


【解决方案1】:

浏览文档显示以下内容 (https://docs.microsoft.com/en-us/sql/t-sql/statements/create-view-transact-sql?view=sql-server-ver15)

可更新视图

只要满足以下条件,就可以通过视图修改底层基表的数据:

Any modifications, including UPDATE, INSERT, and DELETE statements, must reference columns from only one base table.

The columns being modified in the view must directly reference the underlying data in the table columns. The columns cannot be derived in any other way, such as through the following:

    An aggregate function: AVG, COUNT, SUM, MIN, MAX, GROUPING, STDEV, STDEVP, VAR, and VARP.

    A computation. The column cannot be computed from an expression that uses other columns. Columns that are formed by using the set operators UNION, UNION ALL, CROSSJOIN, EXCEPT, and INTERSECT amount to a computation and are also not updatable.

The columns being modified are not affected by GROUP BY, HAVING, or DISTINCT clauses.

TOP is not used anywhere in the select_statement of the view together with the WITH CHECK OPTION clause.

注意到这一点,Comment 的显示架构表明主键是 CommentId 并且没有 PersonId 的唯一约束。

这意味着每个 PersonId 可以有多个评论记录。 如果这是所需的意图,那么为了使它们按照上述限制可编辑,我们将被禁止 对它们进行分组/聚合。

以下内容将允许您编辑它们,但如果您有多个 cmets,则每个 PersonId 可能有多行。

CREATE VIEW dbo.TransactionSummaryComment
AS
SELECT p.PersonId
,f.Cost [FoodTotal]
,e.Cost [EntertainmentTotal]
,c.Comment
FROM Person p
LEFT JOIN (SELECT PersonId, SUM(Cost) [Cost] FROM FoodTransaction GROUP BY  PersonId) f ON p.PersonId = f.PersonId
LEFT JOIN (SELECT PersonId, SUM(Cost) [Cost] FROM EntertainmentTransaction GROUP BY PersonId) e ON p.PersonId = e.PersonId
LEFT JOIN Comment c ON c.PersonId = p.PersonId
WHERE f.Cost IS NOT NULL
OR e.Cost IS NOT NULL

如果意图是每个 PersonId 只有一个评论,即Comment 的架构将主键为PersonId,那么我们知道评论行将只有 每个人只有一条记录,因此视图不会重复。

【讨论】:

  • 效果很好!有效点与评论表。我不希望重复,因为没有人会发表超过一条评论。将 PersonId 作为主键而不是 CommentId 对 PersonId 具有唯一约束以防止列重复有什么好处?
  • 从存储的角度来看,通过不再在表中包含 CommentId 列,您可以为每条记录节省 4 个字节。
  • 另外,评论将只有一个索引而不是两个(只有 PK 与 PK 和唯一)。从规范化的角度来看,Comment 可以是 PersonComment,这可能会使意图更清晰(意见)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-10
  • 2020-05-25
  • 1970-01-01
相关资源
最近更新 更多