sql orderby limit 1 得到的结果不一样

sql orderby limit 1 得到的结果有时候会不一样;
原因是基于非唯一字段的排序 结果集是不确定的,需要再增加一个唯一字段一起来做排序这样就会保证结果一致了;
第一条: select * from 表名 limit 1;(默认是升序排序,取第一条)
最后一条:select * from表名 order by 表_id desc limit 1(降序排序取第一条)

--找到与概率0.5最接近的方法1(得到的概率与方法2一样,只是排名不一样,看情况取值)
SELECT sub_rank,shixin_prob FROM shixin_offline_predict_results WHERE big_hy_name ='nan';
--5982  0.4746192893401015
SELECT sub_rank,shixin_prob FROM shixin_offline_predict_results WHERE shixin_prob < 0.5 AND big_hy_name ='nan' ORDER BY shixin_prob DESC,sub_rank DESC LIMIT 1;
--5983  0.5041050903119869
SELECT sub_rank,shixin_prob FROM shixin_offline_predict_results WHERE shixin_prob >= 0.5 AND big_hy_name ='nan' ORDER BY shixin_prob ASC,sub_rank ASC LIMIT 1;

--找到与概率0.5最接近的方法2
--5976  0.4746192893401015
SELECT sub_rank,shixin_prob FROM shixin_offline_predict_results WHERE shixin_prob < 0.5 AND big_hy_name ='nan' ORDER BY shixin_prob DESC,sub_rank ASC LIMIT 1;
--5984  0.5041050903119869
SELECT sub_rank,shixin_prob FROM shixin_offline_predict_results WHERE shixin_prob >= 0.5 AND big_hy_name ='nan' ORDER BY shixin_prob ASC,sub_rank DESC LIMIT 1;

--找概率的真实的上下界
--5978  0.4746192893401015
SELECT sub_rank,shixin_prob FROM shixin_offline_predict_results WHERE shixin_prob < 0.5 AND big_hy_name ='nan' ORDER BY shixin_prob DESC;
--5983  0.5041050903119869
SELECT sub_rank,shixin_prob FROM shixin_offline_predict_results WHERE shixin_prob >= 0.5 AND big_hy_name ='nan' ORDER BY shixin_prob ASC;
 if CollectUtils.is_empty(row_left):  # 左值未找到,取右值
            return row_right[select_column]
        elif CollectUtils.is_empty(row_right):  # 右值未找到,取左值,因为是一个已知表,一定会存在一边有值;
            return row_left[select_column]
        else:
            # 绝对差值
            abs_left = abs(row_left['shixin_prob'] - prob)
            abs_right = abs(row_right['shixin_prob'] - prob)

            selected_row = row_left if abs_left < abs_right else row_right ##
            #注:词句为了看它的覆盖率,可以拆分成if...else...:
            if abs_left < abs_right:
             selected_row = row_left
        else:
             selected_row = row_right
            return selected_row[select_column] #返回得到的sub_rank值;
SELECT sub_rank,shixin_prob FROM shixin_offline_predict_results WHERE shixin_prob < 0.5 AND big_hy_name ='nan' ORDER BY shixin_prob DESC LIMIT 1; 5996
SELECT sub_rank,shixin_prob FROM shixin_offline_predict_results WHERE shixin_prob >= 0.5 AND big_hy_name ='nan' ORDER BY shixin_prob ASC LIMIT 1; 5983
SELECT sub_rank,shixin_prob FROM shixin_offline_predict_results WHERE shixin_prob < 0.5 AND big_hy_name ='nan' ORDER BY shixin_prob,sub_rank DESC LIMIT 1; 468
SELECT sub_rank,shixin_prob FROM shixin_offline_predict_results WHERE shixin_prob >= 0.5 AND big_hy_name ='nan' ORDER BY shixin_prob,sub_rank ASC LIMIT 1; 5983
SELECT sub_rank,shixin_prob FROM shixin_offline_predict_results WHERE big_hy_name ='nan' #
已知sub_rank是升序,与第二个加了sub_rank中的顺序ASC一致,所以才不会错???、
DBA在和开发沟通/培训过程中要注意这一点 基于非唯一字段的排序 结果集是不确定的。如果业务逻辑对分页或者order by结果集有比较高的严格要求 ,请记得利用唯一键排序。 

select sub_rank from t_features order by prob limit 1
assert检测sub_rank的时候 线上是4834,而先上是4833,
这种语句会导致测试线上线下通不过,原因是基于非唯一字段的排序 结果集是不确定的,需要再增加一个唯一字段一起来做排序这样就会保证结果一致了;

Order by和Limit混合使用引起的问题

如果在order by语句中返回的结果集有很多行,那么非排序的列的返回结果是不确定的,即随机的,所以如果配合limit的话每次返回的结果集的顺序是不固定的,比如下面这个例子

mysql> SELECT * FROM ratings ORDER BY category;

+----+----------+--------+

| id | category | rating |

+----+----------+--------+

|  1 |        1 |   4.5 |

|  5 |        1 |   3.2 |

|  3 |        2 |   3.7 |

|  4 |        2 |   3.5 |

|  6 |        2 |   3.5 |

|  2 |        3 |   5.0 |

|  7 |        3 |   2.7 |

+----+----------+--------+

使用了limit以后,可发现id列和rating列和之前的结果集顺序有出入:

mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;

+----+----------+--------+

| id | category | rating |

+----+----------+--------+

|  1 |        1 |   4.5 |

|  5 |        1 |   3.2 |

|  4 |        2 |   3.5 |

|  3 |        2 |   3.7 |

|  6 |        2 |   3.5 |

+----+----------+--------+

如果你有必要保证每次有相同的结果集,则需要order by你需要的那几列了:

mysql> SELECT * FROM ratings ORDER BY category, id;

+----+----------+--------+

| id | category | rating |

+----+----------+--------+

|  1 |        1 |   4.5 |

|  5 |        1 |   3.2 |

|  3 |        2 |   3.7 |

|  4 |        2 |   3.5 |

|  6 |        2 |   3.5 |

|  2 |        3 |   5.0 |

|  7 |        3 |   2.7 |

+----+----------+--------+

mysql> SELECT * FROM ratings ORDER BY category, id LIMIT 5;

+----+----------+--------+

| id | category | rating |

+----+----------+--------+

|  1 |        1 |   4.5 |

|  5 |        1 |   3.2 |

|  3 |        2 |   3.7 |

|  4 |        2 |   3.5 |

|  6 |        2 |   3.5 |

+----+----------+--------+

猜你喜欢

转载自blog.csdn.net/sinat_26566137/article/details/81131917