按 ID 和更新列对 SQL 中的行进行分组

Posted

技术标签:

【中文标题】按 ID 和更新列对 SQL 中的行进行分组【英文标题】:Group rows in SQL by ID and Update Columns 【发布时间】:2021-02-09 06:15:59 【问题描述】:

我有一个表,其中包含 ID、A1、C1、C2...C20、Country、State、Name 和其他 10 列类似于 country、state、name 的列(A1 是我的主键)

我现有的表是这样的

ID A1 C1 C2 C3 C4 Country State      Pet Name
1  25 1  1  0   1 USA     Texas      Tucker
1  26 1  0  0   0 USA     California Drum 
2  27 0  1  1   0 Canada  BC         Golden
2  28 0  0  0   1 USA     Ohio       Charlie
3  29 1  1  0   0 Mexico  Tabasco    Chelsea

我如何实现这一目标


ID A1 C1 C2 C3 C4 Country State      Pet Name
1  25 1  1  0   1 USA     Texas      Tucker
2  27 0  1  1   1 Canada  BC         Golden
3  29 1  1  0   0 Mexico  Tabasco    Chelsea

我想按 ID 分组,如果有 1 记录在任何时候我希望将其更新为 1,并且我不希望具有不同 A1 的相同 ID 的重复信息的行。如果有一个像 3 这样只有一个 A1 的 ID,我不希望它有任何更改。一旦我得到这个,id 可以成为我的主键,但我希望我可以保留其他列的信息,例如第一次记录的 A1 对应的国家、州、名称(如输出表所示)。

请告诉我如何完成这项工作,谢谢

【问题讨论】:

到目前为止你尝试过什么?为什么它不起作用?为什么要使用UNION ALLJOIN GROUP BY,或者与它们有什么关系?你只有一张桌子,那你找JOINUNION ALL干什么? 我不确定是否可以为此使用 group by 或 Union-all,所以我将其添加为标签。我正在尝试使用案例语句按 ID 分组,但我并没有取得太大的成功。我希望将两行与 ID 连接起来,并在其一对一的位置更新列,并使其余列保持不变 【参考方案1】:

我想你想要聚合:

select id, min(a1) a1, max(c1) c1, max(c2) c2, max(c3) c3, max(c4) c4
from mytable
group by id

如果你想处理更多的列,那就不同了。我会推荐窗口max()s 和row_number()

select *
from (select id, a1,
        max(c1) over(partition by id) c1,
        max(c2) over(partition by id) c2,
        max(c3) over(partition by id) c3,
        max(c4) over(partition by id) c4,
        country,
        state,
        row_number() over(partition by id order by a1) rn
    from mytable
) t
where rn = 1

【讨论】:

这似乎行得通,我该如何处理其他列?就像我有 10 多个其他列一样,我想保留与 min(A1) 对应的值 @learningtocode2k20:您没有显示列的外观以及您希望如何处理它们,所以我只能猜测。也许为每个额外的列添加更多max() 我已经更新了我的问题,抱歉我完全忘记了 @learningtocode2k20:在发布答案后大幅修改问题并不是一个好的做法......请参阅我的编辑。 很抱歉我稍后更新了这个问题,我将把你的问题标记为正确答案,我会尝试使用它。非常感谢您的指导【参考方案2】:

我认为您希望每个id 的最低a1

select t.*
from (select t.*,
             row_number() over (partition by id order by a1 asc) as seqnum
      from t
     ) t
where seqnum = 1;

或者:

select t.*
from t
where t.a1 = (select min(t2.a1) from t t2 where t2.id = t.id);

【讨论】:

是的,这适用于其他列,但它保留了我不想要的 C1..C20 的价值。我希望它更新到没有发生的 1

以上是关于按 ID 和更新列对 SQL 中的行进行分组的主要内容,如果未能解决你的问题,请参考以下文章

SQL:按选定列对记录进行分组

按列对分组数据帧进行采样

按数组中的指定列对行进行分组

如何按列对pyspark中的数据框进行分组并以该列作为键并以记录列表作为其值来获取字典?

更新表以按分组列显示总计 SQL Server 2008 R2

按 PostgreSQL 中的指定列分组