Я намагаюся використовувати оператор select, щоб отримати всі стовпці з певної таблиці MySQL, крім однієї. Чи є простий спосіб це зробити?
Редагувати: У цій таблиці є 53 стовпчики (НЕ МОЙ ДИЗАЙН)
Я намагаюся використовувати оператор select, щоб отримати всі стовпці з певної таблиці MySQL, крім однієї. Чи є простий спосіб це зробити?
Редагувати: У цій таблиці є 53 стовпчики (НЕ МОЙ ДИЗАЙН)
Відповіді:
Насправді є спосіб, для цього потрібно мати дозволи, звичайно ...
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>
<column_name>
У визначеннях mysql (посібник) такого немає. Але якщо у вас дійсно велика кількість стовпців col1
, ..., col100
наступне може бути корисним:
DROP TABLE IF EXISTS temp_tb;
CREATE TEMPORARY TABLE ENGINE=MEMORY temp_tb SELECT * FROM orig_tb;
ALTER TABLE temp_tb DROP col_x;
SELECT * FROM temp_tb;
DROP TABLE IF EXISTS temp_tb;
Чи краще в такому випадку працювати Перегляд?
CREATE VIEW vwTable
as
SELECT
col1
, col2
, col3
, col..
, col53
FROM table
Ви можете зробити:
SELECT column1, column2, column4 FROM table WHERE whatever
не отримуючи колонку3, хоча, можливо, ви шукали більш загальне рішення?
Якщо ви хочете виключити значення поля, наприклад, для питань безпеки / конфіденційної інформації, ви можете отримати цей стовпець як нульовий.
напр
SELECT *, NULL AS salary FROM users
salary
стовпець. Але оскільки він отриманий після *, він перезаписує оригінал. Це не дуже, але це працює.
Наскільки мені відомо, цього немає. Ви можете зробити щось на кшталт:
SELECT col1, col2, col3, col4 FROM tbl
і вручну вибирайте потрібні стовпці. Однак, якщо вам потрібно багато стовпців, ви можете просто зробити:
SELECT * FROM tbl
і просто ігноруйте те, чого ви не хочете.
У вашому конкретному випадку я б запропонував:
SELECT * FROM tbl
якщо ви хочете лише кілька стовпців. Якщо ви хочете лише чотири стовпці, тоді:
SELECT col3, col6, col45, col 52 FROM tbl
було б добре, але якщо ви хочете 50 стовпців, то будь-який код, який робить запит, стане (важко?) важким для читання.
Пробуючи рішення @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;
Якщо стовпець, який ви не хотіли вибрати, мав у ньому величезну кількість даних, і ви не хотіли його включати через проблеми зі швидкістю, а інші стовпці вибираєте часто, я б запропонував вам створити нову таблицю з одним полем, яке ви зазвичай не вибираєте ключем до оригінальної таблиці, і видаліть поле з початкової таблиці. Приєднуйтесь до таблиць, коли це додаткове поле фактично потрібно.
Ви можете використовувати DESCRIBE my_table і використовувати результати цього для динамічного генерування оператора SELECT.
Моя основна проблема - це багато колонок, які я отримую під час приєднання до таблиць. Хоча це не відповідь на ваше запитання (як вибрати всі таблиці, крім певних, з однієї таблиці), я думаю, варто згадати, що ви можете вказати, щоб отримати всі стовпці з певної таблиці, а не просто вказуватиtable.
.
Ось приклад того, як це може бути дуже корисним:
виберіть користувачів. *, phone.meta_value як телефон, zipcode.meta_value як поштовий індекс від користувачів зліва приєднатись до user_meta як телефон увімкнено ((users.user_id = phone.user_id) AND (phone.meta_key = 'телефон')) зліва приєднатися до user_meta як поштовий індекс увімкнено ((users.user_id = zipcode.user_id) AND (zipcode.meta_key = 'zipcode'))
Результатом є всі стовпці з таблиці користувачів та два додаткові стовпчики, які були об'єднані з мета-таблиці.
Мені сподобалась відповідь, @Mahomedalid
окрім цього факту, повідомленого у коментарі @Bill Karwin
. Можлива проблема, яка виникає, @Jan Koritak
правда, я зіткнувся з цим, але я знайшов хитрість у цьому і просто хочу поділитися цим для всіх, хто стикається з проблемою.
ми можемо замінити функцію REPLACE на пункт, де в підзапросі «Підготовлений оператор» такий:
Використовуючи мою назву таблиці та стовпців
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
Добре вказувати стовпці, які ви запитуєте, навіть якщо ви запитуєте всі стовпці.
Тому я б запропонував вам написати ім'я кожного стовпця у виписці (виключаючи той, який ви не хочете).
SELECT
col1
, col2
, col3
, col..
, col53
FROM table
Просто роби
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,";
}
}
Я погоджуюся з "простим" рішенням перерахування всіх стовпців, але це може бути обтяжливим, а помилки друку можуть спричинити багато витраченого часу. Я використовую функцію "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 TABLE_NAME=@table 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
Я погоджуюсь, що недостатньо Select *
, якщо той, який вам не потрібен, як це було зазначено в іншому місці, є БЛОБ, ви не хочете, щоб у вас був цей повз.
Я б створив перегляд з необхідними даними, тоді ви можете Select *
комфортно - якщо програмне забезпечення бази даних їх підтримує. Інше, покладіть величезні дані в іншу таблицю.
Спочатку я думав, що ви можете використовувати регулярні вирази, але, як я читав документи MYSQL, здається, ви не можете. Якби я був ти, я би використовував іншу мову (наприклад, PHP) для створення списку стовпців, який ти хочеш отримати, зберігати його як рядок, а потім використовувати його для генерації SQL.
Я цього хотів і тому створив функцію замість цього.
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", "незалежно стовпець")
Тож у виборі ви можете використовувати його так:
mysql_query("SELECT ".$db->getColsExcept('table',array('id','bigtextcolumn'))." FROM table");
або
mysql_query("SELECT ".$db->getColsExcept('table','bigtextcolumn')." FROM table");
Хоча я згоден з відповіддю Томаса (+1;)), я хотів би додати застереження, що я вважаю, що стовпець, який ви не хочете, містить майже ніякі дані. Якщо вона містить величезну кількість тексту, xml або двійкових крапок, то знайдіть час, щоб вибрати кожен стовпчик окремо. Ваша робота постраждає інакше. Ура!
У відповіді, опублікованій Махомедалідом, є невелика проблема:
Внутрішній код функції заміни замінював " <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 МБ)
На основі @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;
Якщо у вас багато cols, використовуйте цей sql, щоб змінити group_concat_max_len
SET @@group_concat_max_len = 2048;
Можливо, я маю рішення на вказану невідповідність Яна Коритака
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'
Якщо це завжди один і той же стовпець, ви можете створити подання, у якому його немає.
Інакше ні, я не думаю.
Ви можете використовувати SQL для генерування SQL, якщо вам подобається, та оцінюйте його, який він створює. Це загальне рішення, оскільки воно витягує назви стовпців із інформаційної схеми. Ось приклад з командного рядка Unix.
Заміна
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
рядок у запитах, які ви створюєте.
Я хотів би додати ще одну точку зору, щоб вирішити цю проблему, особливо якщо у вас є невелика кількість стовпців, які потрібно видалити.
Ви можете використовувати такий інструмент БД, як MySQL Workbench , щоб генерувати оператор select для вас, тому вам просто потрібно видалити ці стовпці для згенерованого оператора та скопіювати його у свій сценарій SQL.
У MySQL Workbench спосіб її генерування:
Клацніть правою кнопкою миші на таблиці -> надіслати в редактор Sql -> Вибрати всю заяву.
Прийнята відповідь має кілька недоліків.
Усі ці проблеми можна подолати, просто включивши зворотні посилання у 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';
Я досить пізно закидаю відповідь на це, кажу, що це я завжди робив це і, чесно кажучи, його в 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]);
SELECT
заяви - слово навіть не виникає один раз.
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 + антишаблони