【发布时间】:2020-11-16 13:52:17
【问题描述】:
当一个人收到分数时,会在表中添加一个条目@uniqueScores:
Pid | Date | Score
我有一个存储过程返回一个表 @people,其中包含来自 @uniqueScores 的数据(在过去 3 个月内)的分数列
Pid | S1 | S2 | S3 | S4 | S5
我有一个小型测试数据集,但是我无法让任何分数超出注册给用户的第一个分数以显示在 Score2 或更高版本中。
这是我的测试数据集
Pid | Date | Score
#1 | 2020/07/01 | 8
#1 | 2020/09/15 | 8
#2 | 2020/09/21 | 3
#3 | 2020/10/01 | 5
#4 | 2020/10/18 | 6
#4 | 2020/10/31 | 2
我的更新语句,用数据更新 Person 列
BEGIN
UPDATE @people
SET [Score5] = (CASE WHEN ( [p].[Score4] is not null and [p].[Score5] is null ) THEN [us].[Score] ELSE NULL END)
,[Score4] = (CASE WHEN ( [p].[Score3] is not null and [p].[Score4] is null ) THEN [us].[Score] ELSE NULL END)
,[Score3] = (CASE WHEN ( [p].[Score2] is not null and [p].[Score3] is null ) THEN [us].[Score] ELSE NULL END)
,[Score2] = (CASE WHEN ( [p].[Score1] is not null and [p].[Score2] is null ) THEN [us].[Score] ELSE NULL END)
,[Score1] = (CASE WHEN ( [p].[Score1] is null ) THEN [us].[Score] ELSE NULL END)
FROM @people [p] inner join @uniqueScores [us]
on [p].[PersonID] = [us].[PersonID]
WHERE [Date] >= @DateLimit -- within the previous 3 months
END
但是,除了第一个符合条件的值之外,查询不会更新表。返回的表是这样的
Pid | S1 | S2 | S3 | S4 | S5
#1 | 8 | null | null | null | null
#2 | 3 | null | null | null | null
#3 | 5 | null | null | null | null
#4 | 6 | null | null | null | null
不包括第一个不符合条件的表格条目,这很好,但也缺少第 4 个人的第二个分数。
我一直在查看PIVOT、WHILE 和CURSOR,但我离完成这项工作还差得远。我确定我错过了一些简单的东西,但是我看不到它。
【问题讨论】:
-
事实上,这似乎是一个设计缺陷。当一个人获得第 6 分时会发生什么?还是第7?似乎每个分数应该是一行,而不是一列。
-
5 是 5 个月窗口内可能出现的绝对最大分数。
-
直到下周要求更改。 ;)
-
以这种方式返回分数的表是因为显示数据的前端数据表将按照产品所有者的要求将数据以这种方式布局。这些表格的排列方式使得分数(人物、cmets 和媒体)保存在单独的表格中,这意味着可以将每种类型的多个添加到父“报告”中。必须为数据表返回多人分数引发了这个问题。我不是 SQL 方面的专家,但它看起来不像是设计缺陷。表结构只是动态的。
-
展示需求不应该定义设计。像你这样存储分数打破了范式的基本原则之一;因此,为什么它被视为设计缺陷。它不能很好地扩展,并且一旦需求改变就不会工作(即使你认为它们不好,也不意味着它们不会,因为许多不幸的灵魂已经学会了艰难的方式)。
标签: sql sql-server sql-update