【问题标题】:Python Dataframe to SQL QueryPython 数据框到 SQL 查询
【发布时间】:2017-05-17 07:11:23
【问题描述】:

我开发了一个 Python 脚本,它读取一个 CSV 文件,该文件是 SQL 查询的结果(只是一个 select * from table),我对该数据帧执行了一些转换和计算。

我使用以下 Python 命令获取数据框:

result=csv_df.sort_values(by=['column1','column2','column3'],ascending=True)
result=result.drop_duplicates(['column1','column2'])

现在我需要使用 SQL 查询获取同一张表。我在 T-SQL 中尝试过以下方法,但没有成功。

select * from data
    where column1 IN
    (select distinct column1,column2 from data)
 and 
    where column2 IN
    (select distinct column1,column2 from data)
    order by column1,column2;

我是 SQL 语法的新手,有人可以帮我查询吗?

我要做的是从column1column2 的组合中删除所有重复的行。

在 Python 中,我包含 column3 的原因是因为它具有需要丢弃的 NULL 值。

之后我应该创建一个视图来继续执行计算吗?

【问题讨论】:

    标签: python sql sql-server pandas


    【解决方案1】:

    如果我正确理解了您的问题,您可以使用ROW_NUMBER() 函数:

    with VirtTab as (
        select
          t.*,
          row_number()
            over(partition by column1, column2 order by column1, column2) as rn
        from data t
    )
    select * from VirtTab
    where rn = 1
    order by column1, column2;
    

    【讨论】:

    • 我收到Incorrect syntax near the keyword 'where'. 知道为什么会这样吗?
    【解决方案2】:

    据我了解,您需要按 column1、column2 和 column3 排序的所有记录:

    Select * from data order by column1,column2,column3
    

    现在,除此之外,您还想删除participantObjectId 和slipObjectId 列中的重复行。首先根据participantObjectId 和slipObjectId 划分列。下面的查询在上述查询的基础上进行了包装,并添加了另一个字段 id,该字段为每行数据提供唯一值。

    select *, ROW_NUMBER() OVER (PARTITION BY participantObjectId,slipObjectId order by column1,column2,column3) as id
    from (select * from data order by column1,column2,column3)
    

    在此之上,我们添加另一个带有附加条件的 select 语句,以仅选择 id 等于 1 的那些行。

    select * from
    (select *, ROW_NUMBER() OVER (PARTITION BY participantObjectId,slipObjectId order by column1,column2,column3) as id from 
    (Select * from data order by column1,column2,column3
    )) where id=1;
    

    【讨论】:

      【解决方案3】:

      假设表中的 ID 是唯一的,考虑取匹配 column1column2 对中 ID 最低的记录:

      SELECT * FROM data AS main
      WHERE main.ID IN
          (SELECT sub.MinID FROM
             (SELECT column1, column2, Min(ID) As MinID
              FROM data
              GROUP BY column1, column2) AS sub)
      ORDER BY main.column1, main.column2;
      

      或者,JOIN:

      SELECT main.* FROM data AS main
      INNER JOIN 
          (SELECT column1, column2, Min(ID) As MinID
           FROM data
           GROUP BY column1, column2) AS sub
      ON main.ID = sub.MinID
      ORDER BY main.column1, main.column2;
      

      即便如此,EXISTS:

      SELECT main.* FROM data AS main
      WHERE EXISTS
        (SELECT 1 FROM 
            (SELECT column1, column2, Min(ID) As MinID
             FROM data
             GROUP BY column1, column2) sub
         WHERE main.ID = sub.MinID)
      ORDER BY main.column1, main.column2;
      

      以及使用相关计数子查询的非窗口函数查询(与 MySQL、SQLite 和 MS Access 的潜在兼容性)。如果两列中的任何一列是NULL,则此版本会忽略记录:

      SELECT * FROM 
        (SELECT *, 
            (SELECT Count(*) FROM data sub
             WHERE sub.ID <= data.ID
             AND sub.column1 = data.column1
             AND sub.column2 = data.column2) AS rn
         FROM data) AS main
      WHERE main.rn = 1
      

      【讨论】:

      • 这就是我要找的。您能否详细说明第一个答案背后的逻辑?为什么使用 Min(ID)?谢谢!
      • 就像 pandas 一样,drop_duplicates 保持第一个(默认)并随后丢弃匹配项。首先是最小ID。您可以轻松更改为 Max(ID)。
      猜你喜欢
      • 1970-01-01
      • 2015-03-02
      • 1970-01-01
      • 2020-05-03
      • 2021-01-26
      • 1970-01-01
      • 1970-01-01
      • 2015-03-21
      • 2023-03-29
      相关资源
      最近更新 更多