Возможно ли инвертировать оператор select в SQL?

#mysql #sql #database #select

#mysql #sql #База данных #выберите

Вопрос:

Когда я хочу выбрать все столбцы expect foo и bar, то, что я обычно делаю, это просто явно перечисляю все остальные столбцы в операторе select.

select a, b, c, d, ... from ...

Но если таблица содержит дюжину столбцов, это утомительный процесс для простых средств. Вместо этого я хотел бы сделать что-то вроде следующего псевдообъявления:

select * except(foo, bar) from ...

Я также хотел бы знать, существует ли функция для фильтрации строк из результата, состоящего из нескольких столбцов, если несколько строк имеют одинаковое содержимое во всех соответствующих столбцах. Другими словами, повторяющиеся строки будут отфильтрованы.

 ------------------------
A     | B      | C      
------------------------    ====>    ------------------------
A     | B      | C                   A      | B      | C
------------------------             ------------------------
  

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

1. Q1: Нет. Q2: SELECT DISTINCT .

Ответ №1:

Вы можете запросить INFORMATION_SCHEMA базу данных и получить список столбцов (кроме двух) для этой таблицы, например:

 SELECT REPLACE(GROUP_CONCAT(COLUMN_NAME), '<foo,bar>,', '') 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = '<your_table>' AND TABLE_SCHEMA = '<database>';
  

Как только вы получите список столбцов, вы можете использовать его в своем запросе select.

Ответ №2:

Вы можете создать представление на основе этой таблицы со всеми столбцами, кроме этих двух, а затем использовать это представление каждый раз с

 select * from view
  

простая группировка по всему столбцу удалит такие дубликаты. существуют и другие варианты — distinct и row_number.

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

1. Я понимаю ограничение на невозможность обратного выбора, поскольку это нарушило бы контракт между базой данных и клиентским приложением. Каждый запрос может возвращать совершенно другой результат. Но это была бы удобная функция для быстрого просмотра таблицы. При создании представления вам придется проделать еще больше работы для этого простого средства, и оно не подходит.

2. хорошо. Я предполагал, что вы используете эту конкретную таблицу без этих столбцов несколько раз. Это сократит ваши усилия за счет повторного использования этого sql.

Ответ №3:

select * except(foo, bar) from

Это часто запрашиваемая функция в SO. Однако он не соответствует стандарту SQL, и я не знаю ни о каких продуктах SQL, которые его поддерживают. Я предполагаю, что когда менеджеры по продуктам просят своих разработчиков, MVP, группы пользователей и т.д. Оценить энтузиазм по поводу этой перспективной функции, Они в основном слышат: « SELECT * FROM считается опасным, нам нужно защитить новых пользователей, которые не знают, что они делают и т.д.».

Возможно, вам будет полезно использовать NATURAL JOIN вместо INNER JOIN etc, который удаляет дублирующиеся столбцы из результирующего табличного выражения, например

 SELECT * 
  FROM Table1 t1
       INNER JOIN Table2 t2 
          ON t1.foo = t2.foo
             AND t1.bar = t2.bar;
  

в результате появятся два столбца с именем foo и два именованных bar (и, возможно, другие повторяющиеся имена), вероятно, каким-то образом удаленные, например, путем добавления суффикса к именам переменных диапазона, t1 и t2 это INNER JOIN вынудило вас использовать.

Принимая во внимание:

 SELECT * 
  FROM Table1 NATURAL JOIN Table2;
  

не требует использования переменных диапазона (что хорошо), потому что в результате будет только один столбец с именем foo и еще один с именем bar .

И чтобы удалить дублирующиеся строки, а также столбцы, изменил подразумеваемое SELECT ALL * на явное SELECT DISTINCT * , например

 SELECT DISTINCT * 
  FROM Table1 NATURAL JOIN Table2;
  

Выполнение этого может уменьшить вашу потребность в SELECT ALL BUT { these columns } функции, которую вы желаете.

Конечно, если вы это сделаете, вам скажут: « NATURAL JOIN это считается опасным, нам нужно защитить вас от самих себя на случай, если вы не знаете, что делаете, и т.д.» . 🙂