我可以不使用Union子句重写此查询吗

时间:2018-10-01 09:49:33

标签: mysql sql ruby-on-rails

我有一个sliders表。看起来像这样:

+----+-----------+-----------+
| id | video_url | image_url |
+----+-----------+-----------+
| 1  | null      | imgurl1   |
+----+-----------+-----------+
| 2  | null      | imgurl2   |
+----+-----------+-----------+
| 3  | null      | imgurl3   |
+----+-----------+-----------+
| 4  | vidurl1   | null      |
+----+-----------+-----------+

我可以使用此查询实现我想要的:

(SELECT * FROM sliders WHERE image_url IS NOT NULL LIMIT 1)
UNION
(SELECT * FROM sliders WHERE video_url IS NOT NULL LIMIT 1)
UNION
(SELECT * FROM sliders)

基本上,我想要的顺序是:

  1. 第一张图片
  2. 第一个视频
  3. ...
  4. 其他一切

因此,根据示例,结果应为(基于ID)为[1、4、2、3]

是否可以在不使用UNION子句的情况下重新创建?

顺便说一句,我在该项目上使用Ruby on Rails,目前正在使用find_by_sql来执行查询。如果您可以帮助我改用ActiveRecord,那就太好了。

到目前为止,使用ActiveRecord时,我还看不到联合表的方法。

2 个答案:

答案 0 :(得分:2)

您的查询无法解决给出的问题。只有在您应用curl: (60) SSL certificate problem: unable to get local issuer certificate More details here: https://curl.haxx.se/docs/sslcerts.html curl failed to verify the legitimacy of the server and therefore could not establish a secure connection to it. To learn more about this situation and how to fix it, please visit the web page mentioned above. 时,才保证对查询结果进行排序,而您不这样做。您的查询归结为仅仅

ORDER BY

即使您碰巧现在通过查询以期望的顺序获取行,下次运行时也可能有所不同。

(除此之外,您正在应用SELECT * FROM sliders; 而没有LIMIT 1子句,该子句只是任意选择一条记录。您可以通过第一个子查询获得任何图像url。)

您需要一个ORDER BY子句,在其中必须检查行的ID是第一张图像还是第一段视频:

ORDER BY

(这利用了MySQL的true = 1,false =0。通过降序排序,我们在false之前得到true。)

答案 1 :(得分:1)

MySQL中的一种方法是使用变量:

select s.*
from (select s.*,
             (case when image_url is not null then @rn_i := @rn_i + 1 end) as rn_i,
             (case when video_url is not null then @rn_v := @rn_v + 1 end) as rn_v,
      from sliders cross join
           (select @rn_i := 0, @rn_v := 0) params
      order by id
     ) s
order by (rn_i = 1) desc, (rn_v = 1) desc, id asc;