SELECT
@rownum1,
@rownum1 := @rownum1 + 1 AS r_n,
a.trade_date as date_a,
ab.trade_date as date_ab
FROM
stock_daily_data a,
(SELECT @rownum1 := 0) r,
(
SELECT
*
FROM
stock_daily_data
WHERE
stock_code = '300517.SZ'
AND trade_date BETWEEN '2018-05-18'
AND '2018-05-18'  
) ab
WHERE
a.stock_code = '300519.SZ'
AND a.trade_date < ab.trade_date
AND a.trade_date BETWEEN '2018-05-10'
AND '2018-05-14'
ORDER BY
ab.trade_date DESC, a.trade_date DESC结果:上面的r_n可以按从大到小来升序但是如果FROM里面的子查询ab里面的trade_date取值范围是多于一天的话,例如是BETWEEN '2018-05-17' AND '2018-05-18'  ,那么结果会变成是上面的r_n只能从小到大来升序请问各位大佬,为什么会有这样的问题?谢谢指点!

解决方案 »

  1.   

    1,  首先这两个语句结果都是正确的, 排序只保证 order by 后面 的字段
    2,至于会出现r_n不一致, 是因为两者执行的优化策略不一样,前者是按order by后面顺序取值, 后者是取值后再进行排序,MYSQL会认为在第二种情况下用这种方法更快, 你可以前面加explain来验证。随着优化策略不一样,将来还有可能出现第N种@runnum排法, 所以用你@rownum方法来作记录顺序值是不可靠的。
      

  2.   

    感谢指点。
    我按您说的加了EXPLAIN来测试,结果如下:
    取值范围是单天的
    取值范围是两天的
    的确是有所不同,不过我看不懂这个?另外,如果说用@rownum来记录顺序值不可靠,那么应该用什么来记录会可靠呢?求进一步指导,谢谢!
      

  3.   

    把rownum 取出来, 再包裹一层
    SELECT @rownum1,   @rownum1 := @rownum1 + 1 AS r_n, TMP.* FROM ( SELECT .. FROM .. WHERE .. ORDER BY..) as tmp