Предложение IN в SQL-запросе

#sql

#sql

Вопрос:

У меня был один SQL-запрос:

 SELECT NAME
FROM CATEGORY_LANGUAGE 
WHERE 
CATEGORY_ID IN (11, 22)
AND LANGUAGE_ID=1
  

В ЭТОМ ЗАПРОСЕ:

11 -> aa

22 -> bb

Я хочу, чтобы записи возвращались следующим образом:

aa

bb

Во время выполнения запроса возвращается:

bb

aa

Пожалуйста, дайте мне знать, чтобы подробнее проработать мой вопрос.

Комментарии:

1. Наверное, я запутался. Это просто возвращается в неправильном порядке? Если да, не могли бы вы просто указать ПОРЯДОК, чтобы исправить это?

2. Я предполагаю, что вы хотите, чтобы результат был упорядочен так же, как «IN tuple» в вашем SQL, не обязательно в алфавитном порядке?

3. @Doc Brown: «кортеж»?! CATEGORY_ID IN (11, 22) это просто синтаксический сахар для (CATEGORY_ID = 11 OR CATEGORY_ID = 22) . Вы слышали об ассоциативном законе для логического OR? Механизм SQL, безусловно, волен оценивать их в любом порядке, который он считает нужным. И какой тип кортежа упорядочен? 🙂

Ответ №1:

Вот что-то новое:

 SELECT NAME
FROM CATEGORY_LANGUAGE 
WHERE 
    CATEGORY_ID IN (11, 22)
    AND LANGUAGE_ID=1
ORDER BY
    field(CATEGORY_ID, 11, 22)
  

Это предназначено для mysql. Просто убедитесь, что идентификаторы расположены в том же порядке в field() функции, что и в in() функции.

Комментарии:

1. @Doc мы опубликовали в то же время: p так что да, после

2. Итак, кто бы ни проголосовал за это, вы знаете, что это может быть не то решение, за которым охотится OP?

3. @Doc, вот почему я сказал «Из вашего примера», если OP прояснит, я исправлю это, если это действительно то, что нужно OP, он будет счастлив, и все будет весело

4. @Sydenam: Я знаю об этом, иначе я бы отклонил ваш ответ;-) Из названия вопроса, я думаю, можно предположить, что кортеж IN — это то, за чем следует операция.

5. @Doc К сожалению, он, похоже, не участвует в этом обсуждении: p

Ответ №2:

Код SQL

 CATEGORY_ID IN (11, 22)
  

является просто синтаксическим сахаром для

 (CATEGORY_ID = 11 OR CATEGORY_ID = 22)
  

SQL engien может свободно оценивать эти предикаты в любом порядке, который считает нужным (подсказка: OR является ассоциативным).

Это может выглядеть как набор, отношение, таблица, кортеж, список, пакет и т.д., Но это не так.

В SQL действительно есть только одна структура данных: таблица. Поэтому поместите ваши значения в строки промежуточной таблицы (может быть CTE). Таблица не имеет какого-либо внутреннего упорядочения, поэтому, если это является требованием, вам нужно будет указать атрибут порядка сортировки. Затем вы можете JOIN преобразовать промежуточную таблицу в свою целевую базовую таблицу.

Вот некоторый стандартный SQL в качестве примера:

 WITH STAGING (CATEGORY_ID, SORT_ORDER)
     AS
     (
      SELECT CATEGORY_ID, SORT_ORDER
        FROM (
              VALUES (11, 0), 
                     (22, 1)
             ) AS STAGING (CATEGORY_ID, SORT_ORDER)
     )
SELECT C1.NAME, S1.SORT_ORDER
  FROM CATEGORY_LANGUAGE AS C1
       INNER JOIN STAGING AS S1
          ON C1.CATEGORY_ID = S1.CATEGORY_ID 
 WHERE LANGUAGE_ID = 1
 ORDER 
    BY SORT_ORDER;
  

Ответ №3:

Если вы всегда хотите сортировать по category_id:

 SELECT NAME
FROM CATEGORY_LANGUAGE 
WHERE 
CATEGORY_ID IN (11, 22)
AND LANGUAGE_ID=1
ORDER BY CATEGORY_ID
  

Если, с другой стороны, вы всегда хотите иметь тот же порядок, что и в вашем предложении IN, я бы использовал какую-нибудь магию INSTR () (зависит от вашей СУБД, это работает для Oracle; Я вставил дефисы для удобства чтения и чтобы избежать возможных ошибок, если один category_id является префиксом другого):

 SELECT NAME
FROM CATEGORY_LANGUAGE 
WHERE 
CATEGORY_ID IN (11, 22)
AND LANGUAGE_ID=1
ORDER BY INSTR('11-22', TO_CHAR(CATEGORY_ID));
  

Объяснение: TO_CHAR() преобразует CATEGORY_ID в строку, а INSTR() возвращает индекс, в котором вторая строка была найдена в первой — здесь мы используем его, чтобы извлечь порядок сортировки для нашего category_id из ’11-22′.

Комментарии:

1. Предложенный вами запрос работает с некоторым идентификатором и не работает с некоторым идентификатором.

2. @ankitjava У вас есть пример, где это работает не так, как ожидалось?

3. Для id = «1303393383, 1303293381» результат возвращается правильно. Но когда идентификатор изменился на «1301462530, 1301642485», порядок результатов изменился. Пожалуйста, дайте мне знать для дальнейшей разработки.

4. @ankitjava вы правы, произошла ошибка (у меня был обратный порядок аргументов для INSTR ()). Исправлено.

Ответ №4:

 SELECT 
  NAME 
FROM 
  CATEGORY_LANGUAGE  
WHERE  
  CATEGORY_ID IN (11, 22) 
AND 
  LANGUAGE_ID=1 
ORDER BY NAME ASC
  

Возможно, это просто проблема с порядком

Комментарии:

1. Ну, я не верю, что это сработает (нет столбца CATEGORY_LANGUAGE)

2. Спасибо @Doc. я пропустил это

3. и вы, я полагаю, тоже пропустили мой комментарий к вопросу OPs? Кстати, DESC упорядочит вывод в порядке убывания (bb перед aa).

4. Вы правы, DESC будет переключаться на ASC для правильного порядка