Выделить все столбцы, кроме одного в MySQL?

Я пытаюсь использовать оператор select, чтобы получить все столбцы из определенной таблицы MySQL, кроме одного. Есть ли простой способ сделать это?

EDIT: в этой таблице 53 столбца (НЕ МОЙ ДИЗАЙН)

Ответ 1

На самом деле есть способ, для этого вам необходимы разрешения, чтобы сделать это...

SET @sql = CONCAT('SELECT ', (SELECT REPLACE(GROUP_CONCAT(COLUMN_NAME), '<columns_to_omit>,', '') FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '<table>' AND TABLE_SCHEMA = '<database>'), ' FROM <table>');

PREPARE stmt1 FROM @sql;
EXECUTE stmt1;

Замена <table>, <database> and <columns_to_omit>

Ответ 2

В определениях mysql (manual) такой вещи нет. Но если у вас действительно большое количество столбцов col1,..., col100, может быть полезно следующее:

mysql> CREATE TEMPORARY TABLE temp_tb SELECT * FROM orig_tb;
mysql> ALTER TABLE temp_tb DROP col_x;
mysql> SELECT * FROM temp_tb;

Ответ 3

Будет ли просмотр лучше работать в этом случае?

CREATE VIEW vwTable
as  
SELECT  
    col1  
    , col2  
    , col3  
    , col..  
    , col53  
FROM table

Ответ 4

Вы можете сделать:

SELECT column1, column2, column4 FROM table WHERE whatever

без получения столбца3, хотя, возможно, вы искали более общее решение?

Ответ 5

Если вы хотите исключить значение поля, например. для проблем безопасности/конфиденциальной информации вы можете получить этот столбец как null.

например.

SELECT *, NULL AS salary FROM users

Ответ 6

Насколько мне известно, этого не происходит. Вы можете сделать что-то вроде:

SELECT col1, col2, col3, col4 FROM tbl

и вручную выберите нужные столбцы. Однако, если вам нужно много столбцов, вы можете просто сделать следующее:

SELECT * FROM tbl 

и просто игнорируйте то, что вы не хотите.

В вашем конкретном случае я бы предложил:

SELECT * FROM tbl

если вам не нужны только несколько столбцов. Если вам нужны только четыре столбца, то:

SELECT col3, col6, col45, col 52 FROM tbl

будет хорошо, но если вы хотите 50 столбцов, то любой код, который делает запрос, станет (слишком?) трудным для чтения.

Ответ 7

При попытке решения @Mahomedalid и @Junaid я обнаружил проблему. Так подумал об обмене. Если имя столбца имеет пробелы или дефисы, такие как регистрация, запрос будет терпеть неудачу. Простым обходным решением является использование обратных ссылок вокруг имен столбцов. Измененный запрос ниже

SET @SQL = CONCAT('SELECT ', (SELECT GROUP_CONCAT(CONCAT("`", COLUMN_NAME, "`")) FROM
INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'users' AND COLUMN_NAME NOT IN ('id')), ' FROM users');
PREPARE stmt1 FROM @SQL;
EXECUTE stmt1;

Ответ 8

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

Ответ 9

Вы можете использовать DESCRIBE my_table и использовать результаты этого для генерации инструкции SELECT динамически.

Ответ 10

Моя основная проблема - это много столбцов, которые я получаю при соединении таблиц. Хотя это не ответ на ваш вопрос (как выбрать все, кроме определенных столбцов из одной таблицы), я думаю, стоит упомянуть, что вы можете указать table., чтобы получить все столбцы из конкретной таблицы, а не просто указывать .

Вот пример того, как это может быть очень полезно:

select users.*, phone.meta_value as phone, zipcode.meta_value as zipcode

from users

left join user_meta as phone
on ( (users.user_id = phone.user_id) AND (phone.meta_key = 'phone') )

left join user_meta as zipcode
on ( (users.user_id = zipcode.user_id) AND (zipcode.meta_key = 'zipcode') )

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

Ответ 11

Мне понравился ответ от @Mahomedalid, кроме этого, сообщенного в комментарии от @Bill Karwin. Возможная проблема, поднятая @Jan Koritak, верна. Я столкнулся с этим, но я нашел для этого трюк и просто хочу поделиться ею здесь для тех, кто сталкивается с этой проблемой.

мы можем заменить функцию REPLACE предложением where в подзапросе инструкции Prepared следующим образом:

Использование имени моей таблицы и столбца

SET @SQL = CONCAT('SELECT ', (SELECT GROUP_CONCAT(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'users' AND COLUMN_NAME NOT IN ('id')), ' FROM users');
PREPARE stmt1 FROM @SQL;
EXECUTE stmt1;

Итак, это исключает только поле id, но не company_id

Надеюсь, это поможет любому, кто ищет решение.

Привет

Ответ 12

Хорошей практикой является указать столбцы, которые вы запрашиваете, даже если вы запрашиваете все столбцы.

Поэтому я предлагаю вам написать имя каждого столбца в инструкции (исключая тот, который вы не хотите).

SELECT
    col1
    , col2
    , col3
    , col..
    , col53

FROM table

Ответ 13

Просто сделай

SELECT * FROM table WHERE whatever

Затем отпустите столбец в вашем любимом языке программирования: php

while (($data = mysql_fetch_array($result, MYSQL_ASSOC)) !== FALSE) {
   unset($data["id"]);
   foreach ($data as $k => $v) { 
      echo"$v,";
   }      
}

Ответ 14

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

CREATE FUNCTION `getTableColumns`(tablename varchar(100)) 
          RETURNS varchar(5000) CHARSET latin1
BEGIN
  DECLARE done INT DEFAULT 0;
  DECLARE res  VARCHAR(5000) DEFAULT "";

  DECLARE col  VARCHAR(200);
  DECLARE cur1 CURSOR FOR 
    select COLUMN_NAME from information_schema.columns 
    where [email protected] AND TABLE_SCHEMA="yourdatabase" ORDER BY ORDINAL_POSITION;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
  OPEN cur1;
  REPEAT
       FETCH cur1 INTO col;
       IF NOT done THEN 
          set res = CONCAT(res,IF(LENGTH(res)>0,",",""),col);
       END IF;
    UNTIL done END REPEAT;
  CLOSE cur1;
  RETURN res;

Результат возвращает строку с разделителями-запятыми, например...

col1, col2, col3, COL4,... col53

Ответ 15

Я согласен с тем, что этого недостаточно для Select *, если тот, который вам не нужен, как упоминалось в другом месте, является BLOB, вы не хотите, чтобы эта накладная ошибка включалась.

Я бы создал представление с требуемыми данными, тогда вы можете Select * с комфортом - если программное обеспечение базы данных поддерживает их. Иначе, поместите огромные данные в другую таблицу.

Ответ 16

Сначала я думал, что вы можете использовать регулярные выражения, но, поскольку я читал MYSQL docs, похоже, вы не можете. Если бы я был вами, я бы использовал другой язык (например, PHP) для создания списка столбцов, который вы хотите получить, сохраните его как строку, а затем используйте для генерации SQL.

Ответ 17

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

SELECT *
INTO #temp
FROM table

ALTER TABLE #temp DROP COlUMN column_name

SELECT *
FROM #temp

Ответ 18

Мне тоже хотелось, чтобы я создал функцию.

public function getColsExcept($table,$remove){
    $res =mysql_query("SHOW COLUMNS FROM $table");

    while($arr = mysql_fetch_assoc($res)){
        $cols[] = $arr['Field'];
    }
    if(is_array($remove)){
        $newCols = array_diff($cols,$remove);
        return "`".implode("`,`",$newCols)."`";
    }else{
        $length = count($cols);
        for($i=0;$i<$length;$i++){
            if($cols[$i] == $remove)
                unset($cols[$i]);
        }
        return "`".implode("`,`",$cols)."`";
    }
}

Итак, как это работает, вы вводите таблицу, затем столбец, который вам не нужен, или как в массиве: array ( "id", "name", "whatevercolumn" )

Итак, в select вы можете использовать его следующим образом:

mysql_query("SELECT ".$db->getColsExcept('table',array('id','bigtextcolumn'))." FROM table");

или

mysql_query("SELECT ".$db->getColsExcept('table','bigtextcolumn')." FROM table");

Ответ 19

Согласитесь с ответом @Mahomedalid. Но я не хотел делать что-то вроде подготовленного заявления, и я не хотел вводить все поля. Так что у меня было глупое решение. Перейдите в таблицу в phpmyadmin- > sql- > select, он сбрасывает копию запроса и выполняет!:)

Ответ 20

В то время как я согласен с ответом Томаса (+1;)), я хотел бы добавить оговорку, что я предполагаю, что колонка, которую вы не хотите, содержит едва ли какие-либо данные. Если он содержит огромное количество текста, xml или двоичных blobs, то найдите время, чтобы выбрать каждый столбец отдельно. В противном случае ваша производительность будет нарушена. Ура!

Ответ 21

Ответ, отправленный Mahomedalid, имеет небольшую проблему:

Внутри заменяемого функционального кода вместо "<columns_to_delete>," на "эта замена имеет проблему, если поле для замены является последним в строке concat, поскольку последний не имеет запятой char"," и не удаляется из строки.

Мое предложение:

SET @sql = CONCAT('SELECT ', (SELECT REPLACE(GROUP_CONCAT(COLUMN_NAME),
                  '<columns_to_delete>', '\'FIELD_REMOVED\'')
           FROM INFORMATION_SCHEMA.COLUMNS
           WHERE TABLE_NAME = '<table>'
             AND TABLE_SCHEMA = '<database>'), ' FROM <table>');

Замена <table>, <database> и `

Удаленный столбец заменяется строкой "FIELD_REMOVED", в моем случае это работает, потому что я пытался сохранить память. (Поле, которое я удалял, представляет собой BLOB размером около 1 МБ)

Ответ 22

Основываясь на ответе @Mahomedalid, я сделал некоторые улучшения для поддержки "выберите все столбцы, кроме некоторых в mysql"

SET @database    = 'database_name';
SET @tablename   = 'table_name';
SET @cols2delete = 'col1,col2,col3';

SET @sql = CONCAT(
'SELECT ', 
(
    SELECT GROUP_CONCAT( IF(FIND_IN_SET(COLUMN_NAME, @cols2delete), NULL, COLUMN_NAME ) )
    FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tablename AND TABLE_SCHEMA = @database
), 
' FROM ',
@tablename);

SELECT @sql;

Если у вас есть много колоний, используйте этот sql для изменения group_concat_max_len

SET @@group_concat_max_len = 2048;

Ответ 23

Может быть, у меня есть решение для Ян Коритак > Указанное несоответствие

SELECT CONCAT('SELECT ',
( SELECT GROUP_CONCAT(t.col)
FROM
(
    SELECT CASE
    WHEN COLUMN_NAME = 'eid' THEN NULL
    ELSE COLUMN_NAME
    END AS col 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_NAME = 'employee' AND TABLE_SCHEMA = 'test'
) t
WHERE t.col IS NOT NULL) ,
' FROM employee' );

Таблица

SELECT table_name,column_name 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = 'employee' AND TABLE_SCHEMA = 'test'

================================

table_name  column_name
employee    eid
employee    name_eid
employee    sal

================================

Результат запроса:

'SELECT name_eid,sal FROM employee'

Ответ 24

Если это всегда один и тот же столбец, то вы можете создать представление, которое не имеет его в нем.

В противном случае, я так не думаю.

Ответ 25

Вы можете использовать SQL для генерации SQL, если хотите, и оценить SQL, который он производит. Это общее решение, поскольку оно извлекает имена столбцов из информационной схемы. Вот пример из командной строки Unix.

Подставив

  • MYSQL с вашей командой mysql
  • ТАБЛИЦА с именем таблицы
  • EXCLUDEDFIELD с именем исключенного поля
echo $(echo 'select concat("select ", group_concat(column_name) , " from TABLE") from information_schema.columns where table_name="TABLE" and column_name != "EXCLUDEDFIELD" group by "t"' | MYSQL | tail -n 1) | MYSQL

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

Так что-то вроде:

column_list=$(echo 'select group_concat(column_name) from information_schema.columns where table_name="TABLE" and column_name != "EXCLUDEDFIELD" group by "t"' | MYSQL | tail -n 1)

Теперь вы можете повторно использовать строку $column_list в запросах, которые вы создаете.

Ответ 26

Я хотел бы добавить еще одну точку зрения для решения этой проблемы, особенно если у вас есть небольшое количество столбцов для удаления.

Для создания оператора select вы можете использовать инструмент DB, например MySQL Workbench, поэтому вам просто нужно вручную удалить эти столбцы для сгенерированного оператора и скопировать его на ваш SQL script.

В MySQL Workbench способ его создания:

Щелкните правой кнопкой мыши по таблице → отправьте в редактор Sql → Выбрать все выражение.

Ответ 27

Принятый ответ имеет несколько недостатков.

  • Сбой, когда имена таблиц или столбцов требуют обратных кавычек
  • Сбой, если столбец, который вы хотите опустить, является последним в списке
  • Это требует перечисления имени таблицы дважды (один раз для выбора и другого для текста запроса), что является избыточным и ненужным
  • Потенциально может возвращать имена столбцов в неправильном порядке

Все эти проблемы могут быть преодолены путем простого включения обратных галочек в SEPARATOR для вашего GROUP_CONCAT и использования условия WHERE вместо REPLACE(). Для моих целей (и я полагаю, что многие другие) я хотел, чтобы имена столбцов возвращались в том же порядке, в котором они появляются в самой таблице. Чтобы достичь этого, здесь мы используем явное предложение ORDER BY внутри функции GROUP_CONCAT():

SELECT CONCAT(
    'SELECT '',
    GROUP_CONCAT(COLUMN_NAME ORDER BY 'ORDINAL_POSITION' SEPARATOR '',''),
    '' FROM '',
    'TABLE_SCHEMA',
    ''.'',
    TABLE_NAME,
    '';'
)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE 'TABLE_SCHEMA' = 'my_database'
    AND 'TABLE_NAME' = 'my_table'
    AND 'COLUMN_NAME' != 'column_to_omit';

Ответ 28

У меня есть предложение, но нет решения. Если в некоторых из ваших столбцов есть большие наборы данных, попробуйте выполнить следующие действия:

SELECT *, LEFT(col1, 0) AS col1, LEFT(col2, 0) as col2 FROM table

Ответ 29

Мне очень поздно, когда я выхожу из-за ответа на этот вопрос, так я всегда делал это и, честно говоря, в 100 раз лучше и лучше, чем лучший ответ, я только надеюсь, что кто-то это увидит. И найдите это полезным

    //create an array, we will call it here. 
    $here = array();
    //create an SQL query in order to get all of the column names
    $SQL = "SHOW COLUMNS FROM Table";
        //put all of the column names in the array
        foreach($conn->query($SQL) as $row) {
            $here[] = $row[0];
        }
    //now search through the array containing the column names for the name of the column, in this case i used the common ID field as an example
    $key = array_search('ID', $here);
    //now delete the entry
    unset($here[$key]);

Ответ 30

Select * является антипаттерном SQL. Он не должен использоваться в производственном коде по многим причинам, включая:

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

Это означает, что вы, вероятно, отправляете больше данных, чем вам нужно, что вызывает узкие места как на сервере, так и в сети. Если у вас есть внутреннее объединение, шансы отправить больше данных, чем вам нужно, составляют 100%.

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

Это может нарушить представления (я знаю, что это верно для сервера SQl, это может или не может быть правдой в MySQL).

Если кто-то достаточно глуп, чтобы перестроить таблицы со столбцами в другом порядке (что не следует делать, но это происходит постоянно), любой код может сломаться. Особенно код для вставки, например, когда вы неожиданно вводите город в поле address_3, так как без указания, база данных может идти только по порядку столбцов. Это достаточно плохо, когда типы данных изменяются, но хуже, когда поменяемые столбцы имеют один и тот же тип данных, потому что вы можете пойти на какое-то время, вставляя неверные данные, которые бесполезны для очистки. Вы должны заботиться о целостности данных.

Если он используется во вставке, он прервет вставку, если в одну таблицу будет добавлен новый столбец, но не во другую.

Это может сломать триггеры. Проблемы запуска могут быть сложными для диагностики.

Прибавьте все это к тому времени, которое требуется для добавления в имена столбцов (черт возьми, у вас может даже быть интерфейс, который позволяет перетаскивать имена столбцов (я знаю, что в SQL Server я уверен, что могу поспорить, что есть какой-то способ Это инструмент, который вы используете для написания запросов mysql. Давайте посмотрим: "Я могу вызвать проблемы с обслуживанием, я могу вызвать проблемы с производительностью и проблемы с целостностью данных, но эй, я сэкономил пять минут времени на разработку". в определенных столбцах, которые вы хотите.

Я также предлагаю вам прочитать эту книгу: http://www.amazon.com/SQL-Antipatterns-Programming-Pragmatic-Programmers-ebook/dp/B00A376BB2/ref=sr_1_1?s=digital-text&ie=UTF8&qid=1389896688&sr=1- 1 & ключевые слова = SQL + antipatterns