如果上一列值不为空,则更新表中的下一列

     2023-05-08     283

关键词:

【中文标题】如果上一列值不为空,则更新表中的下一列【英文标题】:Update next column in table if previous column value is not null 【发布时间】: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 个人的第二个分数。

我一直在查看PIVOTWHILECURSOR,但我离完成这项工作还差得远。我确定我错过了一些简单的东西,但是我看不到它。

【问题讨论】:

事实上,这似乎是一个设计缺陷。当一个人获得第 6 分时会发生什么?还是第7?似乎每个分数应该是一行,而不是一列。 5 是 5 个月窗口内可能出现的绝对最大分数。 直到下周要求更改。 ;) 以这种方式返回分数的表是因为显示数据的前端数据表将按照产品所有者的要求将数据以这种方式布局。这些表格的排列方式使得分数(人物、cmets 和媒体)保存在单独的表格中,这意味着可以将每种类型的多个添加到父“报告”中。必须为数据表返回多人分数引发了这个问题。我不是 SQL 方面的专家,但它看起来不像是设计缺陷。表结构只是动态的。 展示需求不应该定义设计。像你这样存储分数打破了范式的基本原则之一;因此,为什么它被视为设计缺陷。它不能很好地扩展,并且一旦需求改变就不会工作(即使你认为它们不好,也不意味着它们不会,因为许多不幸的灵魂已经学会了艰难的方式)。 【参考方案1】:

UPDATE 更新每一行一次。预聚合多个更新:

UPDATE p
    SET Score1 = us.score_1,
        Score2 = us.score_2,
        Score3 = us.score_3,
        Score4 = us.score_4,
        Score5 = us.score_5
    FROM @people [p] inner join
         (SELECT us.PersonID,
                 MAX(CASE WHEN seqnum = 1 THEN Score END) as score_1,
                 MAX(CASE WHEN seqnum = 2 THEN Score END) as score_2,
                 MAX(CASE WHEN seqnum = 3 THEN Score END) as score_3,
                 MAX(CASE WHEN seqnum = 4 THEN Score END) as score_4,
                 MAX(CASE WHEN seqnum = 5 THEN Score END) as score_5
          FROM (SELECT us.*,
                       ROW_NUMBER() OVER (PARTITION BY PersonId ORDER BY Date) as seqnum
                FROM @uniqueScores us
                WHERE [Date] >= @DateLimit -- within the previous 3 months
               ) us
          GROUP BY us.PersonID
         ) s
         ON us.PersonID = p.PersonId;

注意:您无需指定分数的顺序。这会将最旧的分数放在首位。如果您想先使用较新的,请使用 ORDER BY DESC

【讨论】:

此代码返回错误:Msg 8120, Level 16, State 1, Line 51 列 '@uniqueScores.Date' 在选择列表中无效,因为它不包含在聚合函数或GROUP BY 子句不确定是否要添加 group by 子句,因为我不是在寻找字段的总和。 @Vurbetan 。 . .糟糕,GROUP BY 在错误的子查询中。 这只是将错误移动到第 60 行和“us.seqnum”。还会在 Max Case 子句中的每个 'Score' colmin 上导致 Invalid Column Name 错误。你也有一个错字“)s”应该是“)我们” 感谢 Gordon 的更新!这已经解决了这个问题。还要注意的是,在先前的查询中,数据首先被预排序为最旧的。 @Vurbetan 。 . .没有“排序表”之类的东西。 SQL 表代表 无序 集。您可以拥有一个按特定顺序排列的标识列。或者你可以有一个聚集索引,它物理上按顺序存储数据——但这些都不能保证数据是按顺序读取的。

如果 Laravel 中的值不为空,如何验证输入字段

】如果Laravel中的值不为空,如何验证输入字段【英文标题】:HowtovalidateaninputfieldifvalueisnotnullinLaravel【发布时间】:2017-08-2210:55:05【问题描述】:我正在尝试使用laravel5.4创建和更新用户这是为创建用户添加的验证。它有效。$this... 查看详情

选择性过滤列值不为空的行 PostgreSQL

】选择性过滤列值不为空的行PostgreSQL【英文标题】:SelectivelyfilterrowswherecolumnvalueisnotnullPostgreSQL【发布时间】:2020-11-2107:58:40【问题描述】:我在Postgres11.0中有下表。col1col2col3col4col51NCT02582996acetaminophen+caffeine+dihydroergotamine+metoclop... 查看详情

从列中的值不为空的 self 表更新表

】从列中的值不为空的self表更新表【英文标题】:Updatetablefromselftablewherevalueinthecolumnisnotnull【发布时间】:2019-01-1506:49:28【问题描述】:我有一个包含值的表:dbidnameuserid------------------------------154xyzNULL987xyzNULL777xyz5111abcNULL745abcNU... 查看详情

如果不为空,Pandas 使用值,否则使用下一列的值

】如果不为空,Pandas使用值,否则使用下一列的值【英文标题】:PandasUseValueifNotNull,ElseUseValueFromNextColumn【发布时间】:2016-06-0212:31:12【问题描述】:给定以下数据框:importpandasaspddf=pd.DataFrame(\'COL1\':[\'A\',np.nan,\'A\'],\'COL2\':[np.nan,... 查看详情

R:获取值不为空的列名

...有这种蔬菜/水果。有没有办法对蔬菜和水果进行分组,如果这个人有蔬菜/水果,则输出列名?输入数据框:id1<-c("id_1",1,NA,NA,NA,1,NA)id2< 查看详情

如果值不为空,如何仅在对象中添加字段? Javascript

】如果值不为空,如何仅在对象中添加字段?Javascript【英文标题】:HowdoIonlyaddthefieldinanobjectifthevalueisn\'tnull?Javascript【发布时间】:2021-12-0510:12:03【问题描述】:我目前正在使用mongoose将数据写入MongoDB集合中的文档,但我不接受... 查看详情

java示例代码_如果一个表中的多个字段可能为空,则更新它们

java示例代码_如果一个表中的多个字段可能为空,则更新它们 查看详情

如果一列不为空,则转换为多列的行

】如果一列不为空,则转换为多列的行【英文标题】:Ifacolumnisnotnullthenconvertintoarowformultiplecolumns【发布时间】:2021-01-2101:44:11【问题描述】:我有一个如下表所示的表格,我希望将col4col5和col6转换为行,但采用我在下面列出的... 查看详情

如果表 A 中的值不为空,我如何从表 B 中获取值

】如果表A中的值不为空,我如何从表B中获取值【英文标题】:HowdoIgetvaluefromTableBifValueinTableAisnotnull【发布时间】:2016-02-1014:22:02【问题描述】:我是SQL查询的新手,但如果我是用我使用多年的编程语言编写的,它看起来像这样... 查看详情

如果其他列不为空,则更新 3 列

】如果其他列不为空,则更新3列【英文标题】:Update3columnsifothercolumnsarenotempty【发布时间】:2020-06-0718:28:43【问题描述】:所以我有6列并且我设置了值。我想要的是如果1-2-3列不为空,我想将这些值设置为4-5-6单元格,否则如果... 查看详情

如何在mysql中获取值不为null的列名

...我有一个只有一个条目的表。我必须获取那些值不为空的列值。请建议我查询MySQL,以便我可以实现它。我的桌子是:在此表中3列具有Null值。所以我不想要这些列,查询应该返回不为空的值。我也可以获取列名吗?就像我想获... 查看详情

剑指offer:二叉树的下一节点(代码片段)

...能在二叉树的所有位置,逐个进行分析。若node的右子树不为空,中序遍历的下一节点是右子树的最左节点。若node的右子树为空,左子树不为空,中序遍历的下一节点是父节点。若node的右子树为空,左子树空,说明是node是叶子... 查看详情

双向循环链表实现(代码片段)

...自己。当链表不为空时,添加操作先把当前头节点的上一跳地址给新元素的上一跳然后让新节点的后驱指针指向head结点,再让head的前驱指针指向新元素。更新head结点,让head结点指向新结点,更新tail结点,让... 查看详情

双向循环链表实现(代码片段)

...自己。当链表不为空时,添加操作先把当前头节点的上一跳地址给新元素的上一跳然后让新节点的后驱指针指向head结点,再让head的前驱指针指向新元素。更新head结点,让head结点指向新结点,更新tail结点,让... 查看详情

mysql如何根据一列值更新另一列的值?

假设有个表aaa如下:a1a210亿20万我想要实现的是,如果a2的值等于万,则更新左侧a1的值除以10000,如何实现呢?在更新表的使用where条件就行了,示例sql,UPDATEaaaSETa1=a1/10000WHEREa2='万';执行这条sql时,先将条件设置详细些,... 查看详情

MERGE - 有条件的“当匹配然后更新”

...GE语句中仅当目标表中的某一列的值为NULL且源表中的相应值不为空时,才有条件地更新记录?你会如何建议重写这个?MERGEdbo.input_3 查看详情

如果 iPhone 应用中的 UITextField 不为空,则启用 UIButton

】如果iPhone应用中的UITextField不为空,则启用UIButton【英文标题】:EnableUIButtonifUITextFieldisnotemptyinIPhoneapp【发布时间】:2012-01-0906:41:57【问题描述】:在我的应用程序中,我在登录页面中有两个文本字段(用户名和密码)和UI按钮... 查看详情

如果满足条件,则移动到嵌套 for 循环中的下一次迭代

】如果满足条件,则移动到嵌套for循环中的下一次迭代【英文标题】:Movingtonextiterationinnestedforloopifconditionmet【发布时间】:2021-05-1515:43:07【问题描述】:我有两个要在for循环中比较的数据框:df_intervals和df_events。对于每个事件... 查看详情