Могу ли я переписать этот запрос без объединения - PullRequest
0 голосов
/ 01 октября 2018

У меня есть 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. Все остальное

Итак, на примере, результат должен быть (на основе идентификатора) равен [1,4,2,3] .

Возможно ли воссоздать без использования предложения UNION?

Кстати, я использую Ruby on Rails в этом проекте и в настоящее время использую find_by_sql для выполнения запроса.Если бы вы могли помочь мне использовать ActiveRecord, это было бы здорово.

На данный момент я не вижу способа объединения таблиц при использовании ActiveRecord.

Ответы [ 2 ]

0 голосов
/ 01 октября 2018

Один из методов в 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;
0 голосов
/ 01 октября 2018

Ваш запрос не является решением данной проблемы.Только тогда гарантируется, что результат запроса будет отсортирован, когда вы применяете ORDER BY, чего вы не делаете.Ваш запрос сводится к простому

SELECT * FROM sliders;

Даже если вам случится получить строки в нужном порядке с вашим запросом сейчас, это может уже отличаться при следующем запуске.

(Кроме того, вы применяете LIMIT 1 без предложения ORDER BY, которое просто выбирает запись произвольно. Вы можете получить любой URL-адрес изображения с первым подзапросом.)

Вам нужен ORDER BY предложение, в котором вы должны проверить, является ли идентификатор строки первым изображением или первым видео:

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. При сортировке в порядке убывания,мы получаем истину перед ложью.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...