【问题标题】:SQL query to delete elements that are not sorted in pandas DataFrameSQL查询删除未在pandas DataFrame中排序的元素
【发布时间】:2016-01-23 01:49:22
【问题描述】:

我正在编写一些代码来优化 NFL 奇幻选秀。因为数据库相当大,我的首要任务是通过删除我知道快速不会构成最佳草案的一部分的条目来缩小它的大小。

每个玩家都有我必须支付的薪水,以及预计的总幻想点数。例如,以下是可能的防御者列表的一部分:

   Id           Position  FPPG    Salary 

0  12542        D         3.8     4000  
1  12534        D         7.5     4100  
2  12548        D         4.6     4200  
3  12532        D         8.2     4300  
4  12547        D         8.4     4400  
5  12545        D         9.2     4500  
6  12525        D         9.0     4600  
7  12553        D         12.3    4700  
8  12544        D         10.8    4800  
9  12531        D         17.0    5000  

我已经编写了 SQL 查询,这些查询将消除受伤的球员,并将在每个薪水价位上消除除预计得分最高的球员之外的所有球员:

d_db = sqldf('SELECT Id, Position, FPPG, Salary from d_db\
            WHERE FPPG = (SELECT max(FPPG) from d_db as db where db.Salary = d_db.Salary) ORDER By Salary',locals())

我现在的任务是消除所有存在更便宜且预计会获得更多积分的玩家。例如,在上面的列表中,第 2 行是无用的,可以删除,因为第 1 行既便宜又具有更高的 FPPG。

换句话说,当数据库按薪水排序时,我想删除 FPPG 列未按升序排序的所有行。理想的最终结果是:

   Id           Position  FPPG    Salary 

0  12542        D         3.8     4000  
1  12534        D         7.5     4100  
2  12532        D         8.2     4300  
3  12547        D         8.4     4400  
4  12545        D         9.2     4500  
5  12553        D         12.3    4700  
6  12531        D         17.0    5000  

有什么建议吗?我似乎无法找出很好地涵盖此内容的 DELETE 语句的 WHERE 条件,所以也许这比单个查询更复杂?

【问题讨论】:

    标签: sql python-2.7 pandas


    【解决方案1】:

    SQL Fiddle Demo

    使用LEFT JOIN,您可以尝试将每个玩家与更好、更便宜的人匹配。

    这个用于调试

    SELECT *
    FROM Table1 t1
    LEFT JOIN Table1 t2
           ON t1."FPPG" < t2."FPPG"
          AND t1."Salary" > t2."Salary"
    

    输出

    | row |    Id | Position | FPPG | Salary |    row |     Id | Position |   FPPG | Salary |
    |-----|-------|----------|------|--------|--------|--------|----------|--------|--------|
    |   0 | 12542 |        D |    4 |   4000 | (null) | (null) |   (null) | (null) | (null) |
    |   1 | 12534 |        D |    8 |   4100 | (null) | (null) |   (null) | (null) | (null) |
    |   2 | 12548 |        D |    5 |   4200 |      1 |  12534 |        D |      8 |   4100 |
    |   3 | 12532 |        D |    8 |   4300 | (null) | (null) |   (null) | (null) | (null) |
    |   4 | 12547 |        D |    8 |   4400 | (null) | (null) |   (null) | (null) | (null) |
    |   5 | 12545 |        D |    9 |   4500 | (null) | (null) |   (null) | (null) | (null) |
    |   6 | 12525 |        D |    9 |   4600 | (null) | (null) |   (null) | (null) | (null) |
    |   7 | 12553 |        D |   12 |   4700 | (null) | (null) |   (null) | (null) | (null) |
    |   8 | 12544 |        D |   11 |   4800 |      7 |  12553 |        D |     12 |   4700 |
    |   9 | 12531 |        D |   17 |   5000 | (null) | (null) |   (null) | (null) | (null) |
    

    您的最终查询,返回不匹配的行 t2."Id" IS NULL

    SELECT t1.*
    FROM Table1 t1
    LEFT JOIN Table1 t2
           ON t1."FPPG" < t2."FPPG"
          AND t1."Salary" > t2."Salary"
    WHERE 
          t2."Id" IS NULL
    

    注意:

    • 我删除了AND t1."Id" &lt;&gt; t2."Id",因为之前的比较已经验证有不同的值。
    • 确保包含FPPGSalary 的索引

    【讨论】:

    • LEFT JOIN 似乎是我想要的。它在正确的轨道上,但最终删除的行数超过了应有的行数。我会从那里玩它,谢谢!编辑:它是倒退的 - 我认为 wqe 想要 t2.Id 为 NULL 的条目。也许我是倒着描述的。
    • 检查我刚刚更新的输出听起来不正确,因为只有在找到更便宜更好的人时才会删除播放器。你能给我举个例子吗?你可以使用我提供的sqlFiddle来测试一下。
    • 这是我所做的,我认为它是这样工作的:sqlfiddle.com/#!15/b312d/5
    • 哦,是的,我正在考虑删除NOT NULL。但正在做一个选择。我修复了查询
    • 感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    • 2018-12-31
    • 2023-04-11
    • 1970-01-01
    • 2015-11-19
    • 2022-01-23
    相关资源
    最近更新 更多