mysql - 我可以在没有 union 子句的情况下重写这个查询吗

标签 mysql sql ruby-on-rails

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

+----+-----------+-----------+
| 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. 其他一切

所以根据例子,结果应该是(based on the id) is [1,4,2,3]

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

顺便说一句,我在这个项目上使用 Ruby on Rails,目前使用 find_by_sql 来执行查询。如果你能帮我改用 ActiveRecord,那就太好了。

截至目前,我还没有看到在使用 ActiveRecord 时合并表的方法。

最佳答案

您的查询无法解决给定的问题。只有当您应用 ORDER BY 时,查询结果才能保证排序,而您没有这样做。您的查询归结为仅仅是

SELECT * FROM sliders;

即使您现在碰巧通过查询获得了所需顺序的行,下次运行时也可能已经不同了。

(除此之外,您应用的 LIMIT 1 没有 ORDER BY 子句,它只是任意选择一条记录。您可以使用第一个子查询。)

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

SELECT *
FROM sliders
ORDER BY
  id = (SELECT MIN(id) FROM sliders WHERE image_url IS NOT NULL) DESC,
  id = (SELECT MIN(id) FROM sliders WHERE video_url IS NOT NULL) DESC,
  id;

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

关于mysql - 我可以在没有 union 子句的情况下重写这个查询吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52588480/

相关文章:

css - 在 Rails 3.2 应用程序中指定最小化文件的用法

java - 使用Java在数据库中插入图像

php - mysql如何存储多个空格?

php - 从其他表格中选择表格中的选项

mysql - 将一列中的值除以另一列中的相应值

sql - 在sql中使用左外连接过滤记录

ruby-on-rails - rails : How to insert a text_field without a form just to test the layout?

php - 在 PHP 中动态生成数组的适当引用

MySQL 进程卡住

ruby-on-rails - 如何使用 Mongoid 执行 runCommand?