【问题标题】:Filling up a column with a value that satisfy conditions from other columns用满足其他列条件的值填充列
【发布时间】:2021-09-15 06:55:12
【问题描述】:

我有如下表格:

con_no     pr_no     flag_1  flag_2
con_002   1000234      1       0
con_002   1000345     -1       0
con_002   1100200      1       1
con_002   1005890      0       0
con_003   1100367      0       0
con_003   1000445      1       1
con_003   1200334     -1       0
con_003   1140567      1       0

现在我想要另一列填充 pr_no,其 flag_2 = 1 并且 flag_1 = 1 在特定 con_no 内。所以结果表应该是这样的

con_no     pr_no     flag_1  flag_2  Parent_pr
con_002   1000234      1       0      1100200 <---This belongs to con_002
con_002   1000345     -1       0      
con_002   1100200      1       1      1100200 <---This belongs to con_002
con_002   1005890      0       0
con_003   1100367      0       0
con_003   1000445      1       1      1000445 <---This belongs to con_003
con_003   1200334     -1       0
con_003   1140567      1       0      1000445 <---This belongs to con_003

如何使用 python (pandas) 或 SQL 实现上述功能。实际上这个表在数据库(postgreSQL)中。所以一个 SQL 查询字符串也可以。

但有一个问题。每次程序运行时,con_no 都会重新洗牌。一些pr_no 可能附加到新的或现有的(但不同的con_no)。

【问题讨论】:

  • SQL 中的用例。要在 Python 中执行此操作,请使用 if-else 语句创建一个函数,通过 pandas 数据框调用此函数。
  • @AyushKesarwani:请详细说明您的代码 sn-p。在 SQL 或 python 中。

标签: python sql postgresql


【解决方案1】:

您应该将表与自身连接起来。如果您的数据位于名为my_table 的表中,则应该可以使用这样的查询:

with cte as (
    select con_no, pr_no
       from my_table
      where flag_2 = 1)
select t.con_no, t.pr_no, t.flog_1, t.flog_2, cte.pr_no as parent_pf
  from my_table as t
  left outer join cte on (cte.con_no = t.con_no and t.flag_1 = 1)

【讨论】:

  • 第 1 部分我了解到您只过滤了那些 pr_noflag_2=1 的数据。第二部分不太清楚。为什么'left outer join
  • left outer join 是从右侧添加列的连接(此处为cte),如果没有对应关系则将其留空。通常的inner join 会将行数限制为on 条件匹配的行数(这意味着您的示例中parent_pr 为空的所有行都不会显示
  • 好的。让我们假设每次程序运行时,这个con_no 都会重新洗牌。 IE。 pr_number 获取另一个 con_no 的标签。那会发生什么?
  • 在这种情况下,如果您再次播放查询,结果当然会改变。如果要存储结果,则需要使用另一个表或使用 pandas 数据框,但这是另一回事(例如,就您谈论重新洗牌数据而言,您是否需要存储所有状态?如果是,如何你会区分它们吗?
  • con_no 发生变化时,pr_no 及其相关标志保持不变。那么如果我使用pr_no 而不是con_no 加入会发生什么?
【解决方案2】:

您可以使用窗口函数和条件逻辑:

select t.*,
       (case when flag_1 = 1
             then max(case when flag_1 = 1 and flag_2 = 1 then pr_no end) over (partition by con_no)
        end) as parent_pr
from t;

实际上,Postgres 支持filter 语法,所以我会这样写:

select t.*,
       (case when flag_1 = 1
             then max(pr_no) filter (where flag_1 = 1 and flag_2 = 1) over (partition by con_no)
        end) as parent_pr
from t;

【讨论】:

  • pr_no 是字符串,不是整数
  • @pythondumb 。 . .和?这有什么不同?
  • max() 如何处理字符串?
  • @pythondumb 。 . .尝试一下。它使用任何默认排序规则,通常是字典顺序。
猜你喜欢
  • 2017-01-08
  • 2022-11-15
  • 2017-12-26
  • 1970-01-01
  • 2020-09-08
  • 2021-01-04
  • 2021-05-12
  • 2022-12-09
  • 1970-01-01
相关资源
最近更新 更多