【问题标题】:Group rows in SQL by ID and Update Columns按 ID 和更新列对 SQL 中的行进行分组
【发布时间】: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 连接起来,并在其一对一的位置更新列,并使其余列保持不变

标签: sql sql-server group-by max greatest-n-per-group


【解决方案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
猜你喜欢
  • 2020-08-08
  • 2021-10-27
  • 1970-01-01
  • 2022-12-16
  • 2020-11-22
  • 2020-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多