53 kolumny? Trzymałbym się SELECT *, jak sugeruje Thomas w tym przypadku ... chyba że ta dodatkowa kolumna zawiera ogromną ilość danych, których odzyskanie byłoby niepożądane ...?
Mike Stone,
Z wyjątkiem jednej kolumny ... Przypuszczam, że wiesz, którą należy zignorować, stąd kolumna INFORMACJE_SCHEMA.Kolumna jest taka.
Kolumna dużych danych jest prawdziwym problemem, gdy przechowywane są dane geograficzne. Kolumny mogą mieć wiele megabajtów. Działają dobrze tam, gdzie klauzule znajdują wiersze, ale często nie chcesz tych danych w wynikach.
Jason
Typowym zastosowaniem tego jest wykluczenie kolumny z identyfikatorem automatycznego przyrostu. Na przykład, aby wybrać dane do wstawienia do innej tabeli, która ma swój własny identyfikator.
ToolmakerSteve
Odpowiedzi:
222
W rzeczywistości istnieje sposób, aby to zrobić, musisz oczywiście mieć uprawnienia ...
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;
Zastąpienie <table>, <database> and <columns_to_omit>
Jest to o wiele gorsze niż tylko określenie kolumn, co jest znaną najlepszą praktyką.
HLGEM
3
To nie działa, jeśli w nazwach kolumn są spacje. Powinien być aktualizowany, aby zawsze otaczał nazwy backticks<column_name>
adamF
3
To również nie zadziała, jeśli kolumna do zignorowania jest ostatnią wymienioną w strukturze tabeli (ponieważ zamiennik nie będzie pasował do końcowej śpiączki).
Vincent Pazeller,
61
W definicjach mysql (manual) nie ma czegoś takiego. Ale jeśli masz naprawdę dużą liczbę kolumn col1, ..., col100przydatne mogą być:
Dał mi komunikat o błędzie w trzecim kroku: „Liczba kolumn nie zgadza się z liczbą wartości w wierszu 1”. Więc zmieniłem krok 2 na „UPDATE temp_tb SET id = NULL” i wtedy zadziałało.
oyvey
1
Ok, to działa. Ale kiedy ponownie uruchomię to zapytanie, pojawia się błąd, że temp_tb już istnieje. Przez ile czasu temp_tb jest w pamięci? Przepraszam, jeśli to głupie pytanie. PS głosował za odpowiedzią.
Karan
2
@Karan Aby wielokrotnie uruchomić to zapytanie, dodaj kolejne polecenie na początku:DROP TABLE IF EXISTS temp_tb;
gregn3,
1
@Karan Aby określić silnik pamięci, użyj polecenia: CREATE TEMPORARY TABLE temp_tb ENGINE=MEMORY (SELECT * FROM orig_tb); w przeciwnym razie domyślnie jest zapisywany na dysku i przetrwa restart serwera. ( dzięki )
gregn3
Doskonała odpowiedź. Aby usunąć wiele kolumn , zapoznaj się z tą odpowiedzią .
HA HA! Tak, jasne. Jak zbudować widok, aby uwzględnić wszystkie ALE jedną kolumnę. Myślę, że widzisz, jak rodzi się oryginalne pytanie. W rzeczywistości znalazłem ten wątek specjalnie, ponieważ chciałem utworzyć widok, który wykluczałby niektóre kolumny, bez zmuszania do jawnego wyświetlania wszystkich pozostałych kolumn w definicji widoku.
Większość wyżej ocenianych odpowiedzi to po prostu znalezienie sposobów na wygenerowanie tego dokładnego zapytania bez ręcznego pisania
mehtunguh
5
W rzeczywistości ze względów konserwacyjnych przydatne jest zapytanie typu „wszystko oprócz”. W przeciwnym razie jawne listy pól muszą zostać zaktualizowane, jeśli nowe pola zostaną dodane później.
leiavoia
1
@lev, to prawda i POWINNY BYĆ !!! B Pamiętaj, że nie wiesz, czy chcesz mieć przyszłe kolumny (mogą to być kolumny metadanych lub te, które nie dotyczą konkretnego ekranu). Nie; chcesz zaszkodzić wydajności, zwracając więcej, niż potrzebujesz (co jest prawdą w 100% przypadków, gdy masz wewnętrzne sprzężenie). Sugeruję, abyś przeczytał, dlaczego select * jest antipatternem SQL.
HLGEM
26
OP stwierdza, że jest> 50 kolumn, więc jest to raczej niepraktyczne.
sierpień
1
@HLGEM Nie bardzo, chciałem wybrać wszystkie kolumny bez utrzymywania zapytania za każdym razem, gdy dodam nową kolumnę, z wyjątkiem jednej z nich, a to po prostu nie zadziała w moim przypadku. Ale i tak zastosowałem dla siebie rozwiązanie Seana O
OverCoder
26
Jeśli chcesz wykluczyć wartość pola, np. Ze względów bezpieczeństwa / poufnych informacji, możesz pobrać tę kolumnę jako null.
Dlaczego? To nie działa Jeśli masz wynagrodzenie w kolumnie, to zapytanie zakończy się wynikiem, że wyniki będą miały dwie kolumny o nazwie wynagrodzenie, jedną pełną zera i jedną z rzeczywistymi wynagrodzeniami.
Myforwik
4
@Myforwik To zapytanie rzeczywiście dodaje drugą salarykolumnę. Ale ponieważ jest pobierany po *, zastępuje oryginał. To nie jest ładne, ale działa.
Sean O
67
SQL zawsze zezwalał na powielanie nazw kolumn w zestawie wyników. Jeśli chcesz, aby to działało, musisz uruchomić je z aplikacją kliencką, która nie obsługuje duplikatów i daje pierwszeństwo ostatniej duplikatowi. Oficjalny klient wiersza polecenia obsługuje duplikaty. HeidiSQL również je obsługuje. SQL Fiddle nie, ale wyświetla pierwszy duplikat, a nie ostatni. Podsumowując: to nie działa .
Álvaro González
9
Oczywiście, że to nie działa. To świetny przykład, dlaczego powinieneś testować swoje odpowiedzi w samym mysql, zamiast w bibliotekach, które komunikują się z mysql.
Myforwik
8
@SeanO, @ Alastair, @ Wszyscy, nie zastępują. Serwer nadal zwraca wrażliwe dane.
Pacerier
22
Według mojej najlepszej wiedzy nie ma. Możesz zrobić coś takiego:
SELECT col1, col2, col3, col4 FROM tbl
i ręcznie wybierz odpowiednie kolumny. Jeśli jednak chcesz mieć wiele kolumn, możesz po prostu zrobić:
SELECT*FROM tbl
i po prostu zignoruj to, czego nie chcesz.
W twoim konkretnym przypadku sugerowałbym:
SELECT*FROM tbl
chyba że chcesz tylko kilka kolumn. Jeśli chcesz tylko cztery kolumny, to:
SELECT col3, col6, col45, col 52FROM tbl
byłoby dobrze, ale jeśli chcesz 50 kolumn, to każdy kod, który powoduje, że zapytanie będzie (zbyt?) trudne do odczytania.
Wybierz * to zawsze zły wybór. Nie polecam tego. Przeczytaj, dlaczego jest to SQl Antipattern.
HLGEM
18
Podczas próby rozwiązania przez @Mahomedalid i @Junaid znalazłem problem. Więc pomyślałem o udostępnieniu tego. Jeśli nazwa kolumny zawiera spacje lub łączniki, takie jak zameldowanie, zapytanie zakończy się niepowodzeniem. Prostym obejściem jest użycie znaku wstecz wokół nazw kolumn. Zmodyfikowane zapytanie znajduje się poniżej
SET@SQL = CONCAT('SELECT ',(SELECT GROUP_CONCAT(CONCAT("`", COLUMN_NAME,"`"))FROM
INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME ='users'AND COLUMN_NAME NOTIN('id')),' FROM users');
PREPARE stmt1 FROM@SQL;EXECUTE stmt1;
Jeśli kolumna, której nie chciałeś wybrać, zawierała w sobie ogromną ilość danych, a nie chciałeś dołączyć jej z powodu problemów z prędkością, a często wybierasz inne kolumny, sugerowałbym utworzenie nowej tabeli z jednym polem, którego zwykle nie wybiera się za pomocą klucza do oryginalnej tabeli i usuwa pole z oryginalnej tabeli. Dołącz do tabel, gdy to dodatkowe pole jest rzeczywiście wymagane.
Moim głównym problemem jest wiele kolumn, które pojawiają się podczas łączenia tabel. Chociaż nie jest to odpowiedź na twoje pytanie (jak wybrać wszystkie kolumny z jednej tabeli z wyjątkiem niektórych ), myślę, że warto wspomnieć, że możesz określić, aby uzyskać wszystkie kolumny z określonej tabeli, zamiast po prostu określać .table.
Oto przykład, w jaki sposób może to być bardzo przydatne:
wybierz użytkowników. *, phone.meta_value jako telefon, zipcode.meta_value jako kod pocztowy
od użytkowników
lewo dołącz do user_meta jako telefon
on ((users.user_id = phone.user_id) AND (phone.meta_key = 'phone'))
lewo dołącz do user_meta jako kod pocztowy
on ((users.user_id = zipcode.user_id) ORAZ (zipcode.meta_key = 'zipcode'))
Wynikiem są wszystkie kolumny z tabeli użytkowników i dwie dodatkowe kolumny, które zostały połączone z tabeli meta.
dziękuję, muszę wybrać wszystkie kolumny pierwszego stołu i tylko jedno pole z drugiego stołu podczas łączenia, a twoja odpowiedź pomogła mi.
mohammad falahat
5
Podobała mi się odpowiedź @Mahomedalidpoza tym faktem podana w komentarzu od @Bill Karwin. Możliwy problem podniesiony przez @Jan Koritakto prawda. Stawiłem temu czoła, ale znalazłem sztuczkę i po prostu chcę ją tutaj udostępnić każdemu, kto napotka problem.
możemy zamienić funkcję REPLACE na klauzulę where w zapytaniu podrzędnym instrukcji Prepared w następujący sposób:
Używam nazwy mojej tabeli i kolumny
SET@SQL = CONCAT('SELECT ',(SELECT GROUP_CONCAT(COLUMN_NAME)FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME ='users'AND COLUMN_NAME NOTIN('id')),' FROM users');
PREPARE stmt1 FROM@SQL;EXECUTE stmt1;
Działa jak umowa z kodem i patrząc na zapytanie, dokładnie wiesz, jakie dane możesz z niego wyodrębnić bez patrzenia na schemat tabeli.
mbillard
6
@kodecraft: To dobra praktyka z tego samego powodu, dla którego dobrą praktyką jest zawsze zwracanie tego samego typu z funkcji (nawet jeśli pracujesz w języku, w którym nie jest to wymuszone). Zasadniczo tylko zasada najmniejszej niespodzianki.
Daniel Pryden,
4
Po prostu zrób
SELECT*FROMtableWHERE whatever
Następnie upuść kolumnę w swoim ulubionym języku programowania: php
Chyba że kolumna, którą chcesz wykluczyć, to ogromny BLOB lub coś takiego.
Bill Karwin
1
Jest to złe, jeśli próbujesz uniknąć zmarnowanych danych.
Kristopher Ives,
1 kolumna z 53 nie powinna mieć znaczenia. Jeśli tak, to prawdopodobnie zły projekt.
Petr Peller,
1
SElect * jest antipatternem SQL i nigdy nie powinien być używany w kodzie produkcyjnym.
HLGEM
1
Nie zgadzam się, że SELECT * jest rodzajem anty-wzorca, którego „nigdy” nie należy używać w kodzie produkcyjnym. Jest o wiele wyraźniej, że wszystkie kolumny zostały pobrane - w porównaniu do odsyłaczy do długiej listy kolumn, które mogą, ale nie muszą, być wszystkimi polami. Jest też, oczywiście, znacznie szybsze kodowanie. I jest wiele, wiele przypadków, w których pola tabeli będą dokładnie odpowiadać polom w widoku lub formularzu.
Geoff Kendall,
4
Zgadzam się z „prostym” rozwiązaniem wyszczególnienia wszystkich kolumn, ale może to być uciążliwe, a literówki mogą powodować wiele straconego czasu. Korzystam z funkcji „getTableColumns”, aby pobrać nazwy moich kolumn odpowiednie do wklejenia do zapytania. Następnie wszystko, co muszę zrobić, to usunąć te, których nie chcę.
CREATEFUNCTION`getTableColumns`(tablename varchar(100))
RETURNS varchar(5000) CHARSET latin1
BEGINDECLARE done INT DEFAULT0;DECLARE res VARCHAR(5000)DEFAULT"";DECLARE col VARCHAR(200);DECLARE cur1 CURSORFORselect COLUMN_NAME from information_schema.columns
where TABLE_NAME=@tableAND TABLE_SCHEMA="yourdatabase"ORDERBY ORDINAL_POSITION;DECLARECONTINUE HANDLER FORNOT FOUND SET done =1;OPEN cur1;
REPEAT
FETCH cur1 INTO col;IFNOT done THENset res = CONCAT(res,IF(LENGTH(res)>0,",",""),col);ENDIF;
UNTIL done END REPEAT;CLOSE cur1;RETURN res;
Twój wynik zwraca ciąg rozdzielany przecinkami, na przykład ...
Będzie to strasznie wolne dla każdego stołu o średniej wielkości.
Joel
3
Zgadzam się, że nie wystarczy Select *, że jeśli ten, którego nie potrzebujesz, jak wspomniano w innym miejscu, jest BLOBEM, nie chcesz, aby ten napowietrzny wkradł się.
Chciałbym utworzyć widok z wymaganych danych, a następnie można Select *w komfortowych warunkach --if oprogramowanie bazy danych obsługuje je. W przeciwnym razie umieść ogromne dane w innej tabeli.
Na początku myślałem, że możesz użyć wyrażeń regularnych, ale kiedy czytałem dokumenty MYSQL , wydaje się, że nie możesz. Gdybym był tobą, użyłbym innego języka (np. PHP), aby wygenerować listę kolumn, które chcesz uzyskać, zapisać go jako ciąg, a następnie użyć go do wygenerowania kodu SQL.
Zgadzam się z odpowiedzią @ Mahomedalid, ale nie chciałem robić czegoś takiego jak przygotowane oświadczenie i nie chciałem wpisywać wszystkich pól, więc to, co miałem, było głupim rozwiązaniem.
Przejdź do tabeli w phpmyadmin-> sql-> select, zrzuci zapytanie: skopiuj, zamień i gotowe! :)
Chociaż zgadzam się z odpowiedzią Thomasa (+1;)), chciałbym dodać zastrzeżenie, że zakładam, że kolumna, której nie chcesz, nie zawiera prawie żadnych danych. Jeśli zawiera ogromne ilości tekstu, xml lub binarnych obiektów blob, poświęć czas na wybranie każdej kolumny osobno. Twoja wydajność ucierpi inaczej. Twoje zdrowie!
Odpowiedź wysłana przez Mahomedalid ma mały problem:
Wewnątrz kodu funkcji zastępowania zastępowano „ <columns_to_delete>,” przez „”, to zastąpienie ma problem, jeśli pole do zamiany jest ostatnim z ciągu konkat, ponieważ ostatni nie ma przecinka char „” i nie jest usuwany z ciąg.
Moja propozycja:
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>');
Wymiana <table>, <database>i `
Usunięta kolumna zostaje zastąpiona ciągiem „FIELD_REMOVED”. W moim przypadku działa to, ponieważ próbowałem zabezpieczyć pamięć. (Pole, które usunąłem, to BLOB o wielkości około 1 MB)
Być może mam rozwiązanie wskazanej rozbieżności Jana Koritaka
SELECT CONCAT('SELECT ',(SELECT GROUP_CONCAT(t.col)FROM(SELECTCASEWHEN COLUMN_NAME ='eid'THENNULLELSE COLUMN_NAME
ENDAS col
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME ='employee'AND TABLE_SCHEMA ='test') t
WHERE t.col ISNOTNULL),' FROM employee');
Stół :
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
Możesz użyć SQL do wygenerowania SQL, jeśli chcesz i oceń SQL, który produkuje. Jest to ogólne rozwiązanie, ponieważ wyodrębnia nazwy kolumn ze schematu informacyjnego. Oto przykład z wiersza poleceń systemu Unix.
Zastępstwo
MYSQL za pomocą polecenia mysql
TABELA z nazwą tabeli
EXCLUDEDFIELD z wykluczoną nazwą pola
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
Naprawdę będziesz musiał tylko wyodrębnić nazwy kolumn w ten sposób tylko raz, aby zbudować listę kolumn z wyłączeniem tej kolumny, a następnie po prostu użyj utworzonego zapytania.
Więc coś takiego:
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)
Teraz możesz ponownie wykorzystać $column_listciąg w tworzonych zapytaniach.
Chciałbym dodać inny punkt widzenia w celu rozwiązania tego problemu, zwłaszcza jeśli masz do usunięcia niewielką liczbę kolumn.
Możesz użyć narzędzia DB, takiego jak MySQL Workbench , aby wygenerować dla siebie instrukcję select, więc musisz ręcznie usunąć te kolumny z wygenerowanej instrukcji i skopiować ją do skryptu SQL.
W MySQL Workbench sposobem na jego wygenerowanie jest:
Kliknij prawym przyciskiem myszy tabelę -> wyślij do edytora Sql -> Wybierz wszystko.
Nie udaje się, gdy nazwy tabeli lub kolumny wymagają odwrotnych ustawień
Nie powiedzie się, jeśli kolumna, którą chcesz pominąć, jest ostatnia na liście
Wymaga dwukrotnego wpisania nazwy tabeli (raz dla zaznaczenia i drugiego dla tekstu zapytania), co jest zbędne i niepotrzebne
Może potencjalnie zwrócić nazwy kolumn w niewłaściwej kolejności
Wszystkie te problemy można przezwyciężyć, po prostu włączając backticks w SEPARATORfor GROUP_CONCATi używając WHEREwarunku zamiast REPLACE(). Dla moich celów (i wyobrażam sobie wielu innych) chciałem, aby nazwy kolumn były zwracane w tej samej kolejności, w jakiej pojawiają się w samej tabeli. Aby to osiągnąć, używamy wyraźnej ORDER BYklauzuli wewnątrz GROUP_CONCAT()funkcji:
Jestem dość późno, próbując znaleźć odpowiedź na to pytanie. Mówię to w ten sposób, że zawsze tak robiłem. Szczerze mówiąc, jest on 100 razy lepszy i ładniejszy niż najlepsza odpowiedź, mam tylko nadzieję, że ktoś to zobaczy. I uznaj to za przydatne
//create an array, we will call it here.$here = array();//create an SQL query inorderto get allof the column names
$SQL ="SHOW COLUMNS FROM Table";//put allof 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]);
Być może jest to schludne, ale nie odpowiada na pytanie: nie pytał o php, a ty nie podajesz instrukcji select ani wyniku tego, czego chce, a jedynie tablicę php zawierającą kolumny, których chce.
gou1
2
–1. To nie jest kod SQL i nie ma SELECTtu żadnej instrukcji - słowo nie pojawia się ani razu.
Frungi
Jest to o tyle przyjemniejsze, o ile (a) wygodniej jest Ci posługiwać się PHP niż SQL, lub (b) lubisz rozkładać swój kod na wiele wierszy, aby był bardziej czytelny. Przyznaję punkt (b). Twoje podejście byłoby również mniej wydajne, chociaż różnica byłaby niewielka w wielu przypadkach użycia. Zobacz także inne komentarze do twojego pytania. Nie warto o tym krzyczeć, więc sugeruj usunięcie nieodpowiedniego komentarza z pierwotnego pytania.
mc0e,
-5
Wybierz * to antipattern SQL. Nie należy go używać w kodzie produkcyjnym z wielu powodów, w tym:
Przetwarzanie zajmuje trochę dłużej. Kiedy rzeczy są uruchamiane miliony razy, te małe kawałki mogą mieć znaczenie. Powolna baza danych, w której powolność jest powodowana przez tego rodzaju niechlujne kodowanie, jest najtrudniejsza do dostrojenia.
Oznacza to, że prawdopodobnie wysyłasz więcej danych niż potrzebujesz, co powoduje wąskie gardła zarówno serwera, jak i sieci. Jeśli masz połączenie wewnętrzne, szanse na wysłanie większej liczby danych niż potrzebujesz to 100%.
Powoduje to problemy konserwacyjne, zwłaszcza gdy dodałeś nowe kolumny, których nie chcesz widzieć wszędzie. Ponadto, jeśli masz nową kolumnę, może być konieczne zrobienie czegoś z interfejsem, aby ustalić, co zrobić z tą kolumną.
Może to popsuć widoki (wiem, że jest to prawdą na serwerze SQl, może być lub nie być prawdą w mysql).
Jeśli ktoś jest wystarczająco głupi, aby odbudować tabele z kolumnami w innej kolejności (czego nie powinieneś robić, ale zdarza się to cały czas), wszelkiego rodzaju kod może się zepsuć. W szczególności kod dla wstawki, na przykład, gdy nagle wpisujesz miasto w polu adres_3, ponieważ nie określono, baza danych może przechodzić tylko w kolejności kolumn. Jest to wystarczająco złe, gdy zmieniają się typy danych, ale gorzej, gdy zamienione kolumny mają ten sam typ danych, ponieważ można czasem wstawić złe dane, które są bałaganem do wyczyszczenia. Musisz dbać o integralność danych.
Jeśli zostanie zastosowany we wstawce, spowoduje uszkodzenie wkładki, jeśli nowa kolumna zostanie dodana do jednej tabeli, ale nie do drugiej.
Może to spowodować uszkodzenie wyzwalaczy. Problemy z wyzwalaczem mogą być trudne do zdiagnozowania.
Zsumuj to w stosunku do czasu potrzebnego na dodanie nazw kolumn (do cholery możesz nawet mieć interfejs, który pozwala ci przeciągać nazwy kolumn (wiem, że robię to w SQL Server, założę się, że jest jakiś sposób na zrób to narzędzie, którego używasz do pisania zapytań mysql.) Zobaczmy: „Mogę powodować problemy z konserwacją, mogę powodować problemy z wydajnością i problemy z integralnością danych, ale hej, zaoszczędziłem pięć minut na programowaniu”. w konkretnych kolumnach, które chcesz.
Odpowiedzi:
W rzeczywistości istnieje sposób, aby to zrobić, musisz oczywiście mieć uprawnienia ...
Zastąpienie
<table>, <database> and <columns_to_omit>
źródło
<column_name>
W definicjach mysql (manual) nie ma czegoś takiego. Ale jeśli masz naprawdę dużą liczbę kolumn
col1
, ...,col100
przydatne mogą być:źródło
DROP TABLE IF EXISTS temp_tb;
CREATE TEMPORARY TABLE temp_tb ENGINE=MEMORY (SELECT * FROM orig_tb);
w przeciwnym razie domyślnie jest zapisywany na dysku i przetrwa restart serwera. ( dzięki )Czy widok działałby lepiej w tym przypadku?
źródło
Możesz to zrobić:
bez zdobywania column3, chociaż być może szukałeś bardziej ogólnego rozwiązania?
źródło
Jeśli chcesz wykluczyć wartość pola, np. Ze względów bezpieczeństwa / poufnych informacji, możesz pobrać tę kolumnę jako null.
na przykład
źródło
salary
kolumnę. Ale ponieważ jest pobierany po *, zastępuje oryginał. To nie jest ładne, ale działa.Według mojej najlepszej wiedzy nie ma. Możesz zrobić coś takiego:
i ręcznie wybierz odpowiednie kolumny. Jeśli jednak chcesz mieć wiele kolumn, możesz po prostu zrobić:
i po prostu zignoruj to, czego nie chcesz.
W twoim konkretnym przypadku sugerowałbym:
chyba że chcesz tylko kilka kolumn. Jeśli chcesz tylko cztery kolumny, to:
byłoby dobrze, ale jeśli chcesz 50 kolumn, to każdy kod, który powoduje, że zapytanie będzie (zbyt?) trudne do odczytania.
źródło
Podczas próby rozwiązania przez @Mahomedalid i @Junaid znalazłem problem. Więc pomyślałem o udostępnieniu tego. Jeśli nazwa kolumny zawiera spacje lub łączniki, takie jak zameldowanie, zapytanie zakończy się niepowodzeniem. Prostym obejściem jest użycie znaku wstecz wokół nazw kolumn. Zmodyfikowane zapytanie znajduje się poniżej
źródło
Jeśli kolumna, której nie chciałeś wybrać, zawierała w sobie ogromną ilość danych, a nie chciałeś dołączyć jej z powodu problemów z prędkością, a często wybierasz inne kolumny, sugerowałbym utworzenie nowej tabeli z jednym polem, którego zwykle nie wybiera się za pomocą klucza do oryginalnej tabeli i usuwa pole z oryginalnej tabeli. Dołącz do tabel, gdy to dodatkowe pole jest rzeczywiście wymagane.
źródło
Możesz użyć DESCRIBE moja_tabela i użyć jej wyników do dynamicznego generowania instrukcji SELECT.
źródło
Moim głównym problemem jest wiele kolumn, które pojawiają się podczas łączenia tabel. Chociaż nie jest to odpowiedź na twoje pytanie (jak wybrać wszystkie kolumny z jednej tabeli z wyjątkiem niektórych ), myślę, że warto wspomnieć, że możesz określić, aby uzyskać wszystkie kolumny z określonej tabeli, zamiast po prostu określać .
table.
Oto przykład, w jaki sposób może to być bardzo przydatne:
Wynikiem są wszystkie kolumny z tabeli użytkowników i dwie dodatkowe kolumny, które zostały połączone z tabeli meta.
źródło
Podobała mi się odpowiedź
@Mahomedalid
poza tym faktem podana w komentarzu od@Bill Karwin
. Możliwy problem podniesiony przez@Jan Koritak
to prawda. Stawiłem temu czoła, ale znalazłem sztuczkę i po prostu chcę ją tutaj udostępnić każdemu, kto napotka problem.możemy zamienić funkcję REPLACE na klauzulę where w zapytaniu podrzędnym instrukcji Prepared w następujący sposób:
Używam nazwy mojej tabeli i kolumny
To wyklucza tylko pole,
id
ale niecompany_id
źródło
Dobrą praktyką jest określenie zapytanych kolumn, nawet jeśli zapytania dotyczą wszystkich kolumn.
Proponuję więc wpisać nazwę każdej kolumny w zestawieniu (z wyjątkiem tej, której nie chcesz).
źródło
Po prostu zrób
Następnie upuść kolumnę w swoim ulubionym języku programowania: php
źródło
Zgadzam się z „prostym” rozwiązaniem wyszczególnienia wszystkich kolumn, ale może to być uciążliwe, a literówki mogą powodować wiele straconego czasu. Korzystam z funkcji „getTableColumns”, aby pobrać nazwy moich kolumn odpowiednie do wklejenia do zapytania. Następnie wszystko, co muszę zrobić, to usunąć te, których nie chcę.
Twój wynik zwraca ciąg rozdzielany przecinkami, na przykład ...
źródło
Tak, chociaż może to być wysokie I / O w zależności od tabeli, oto obejście tego problemu.
źródło
Zgadzam się, że nie wystarczy
Select *
, że jeśli ten, którego nie potrzebujesz, jak wspomniano w innym miejscu, jest BLOBEM, nie chcesz, aby ten napowietrzny wkradł się.Chciałbym utworzyć widok z wymaganych danych, a następnie można
Select *
w komfortowych warunkach --if oprogramowanie bazy danych obsługuje je. W przeciwnym razie umieść ogromne dane w innej tabeli.źródło
Na początku myślałem, że możesz użyć wyrażeń regularnych, ale kiedy czytałem dokumenty MYSQL , wydaje się, że nie możesz. Gdybym był tobą, użyłbym innego języka (np. PHP), aby wygenerować listę kolumn, które chcesz uzyskać, zapisać go jako ciąg, a następnie użyć go do wygenerowania kodu SQL.
źródło
Też tego chciałem, więc zamiast tego stworzyłem funkcję.
Więc działa to tak, że wchodzisz do tabeli, a następnie do kolumny, której nie chcesz lub jak w tablicy: array („id”, „name”, „whatcolumn”)
Więc w select możesz użyć tego w następujący sposób:
lub
źródło
Zgadzam się z odpowiedzią @ Mahomedalid, ale nie chciałem robić czegoś takiego jak przygotowane oświadczenie i nie chciałem wpisywać wszystkich pól, więc to, co miałem, było głupim rozwiązaniem.
Przejdź do tabeli w phpmyadmin-> sql-> select, zrzuci zapytanie: skopiuj, zamień i gotowe! :)
źródło
Chociaż zgadzam się z odpowiedzią Thomasa (+1;)), chciałbym dodać zastrzeżenie, że zakładam, że kolumna, której nie chcesz, nie zawiera prawie żadnych danych. Jeśli zawiera ogromne ilości tekstu, xml lub binarnych obiektów blob, poświęć czas na wybranie każdej kolumny osobno. Twoja wydajność ucierpi inaczej. Twoje zdrowie!
źródło
Odpowiedź wysłana przez Mahomedalid ma mały problem:
Wewnątrz kodu funkcji zastępowania zastępowano „
<columns_to_delete>,
” przez „”, to zastąpienie ma problem, jeśli pole do zamiany jest ostatnim z ciągu konkat, ponieważ ostatni nie ma przecinka char „” i nie jest usuwany z ciąg.Moja propozycja:
Wymiana
<table>
,<database>
i `Usunięta kolumna zostaje zastąpiona ciągiem „FIELD_REMOVED”. W moim przypadku działa to, ponieważ próbowałem zabezpieczyć pamięć. (Pole, które usunąłem, to BLOB o wielkości około 1 MB)
źródło
W oparciu o odpowiedź @Mahomedalid wprowadziłem kilka ulepszeń w celu obsługi „zaznacz wszystkie kolumny oprócz niektórych w mysql”
Jeśli masz dużo cols, użyj tej sql, aby zmienić group_concat_max_len
źródło
Być może mam rozwiązanie wskazanej rozbieżności Jana Koritaka
Stół :
================================
================================
Wynik zapytania:
źródło
Jeśli zawsze jest to ta sama kolumna, możesz utworzyć widok, w którym jej nie ma.
W przeciwnym razie nie, nie sądzę.
źródło
Możesz użyć SQL do wygenerowania SQL, jeśli chcesz i oceń SQL, który produkuje. Jest to ogólne rozwiązanie, ponieważ wyodrębnia nazwy kolumn ze schematu informacyjnego. Oto przykład z wiersza poleceń systemu Unix.
Zastępstwo
Naprawdę będziesz musiał tylko wyodrębnić nazwy kolumn w ten sposób tylko raz, aby zbudować listę kolumn z wyłączeniem tej kolumny, a następnie po prostu użyj utworzonego zapytania.
Więc coś takiego:
Teraz możesz ponownie wykorzystać
$column_list
ciąg w tworzonych zapytaniach.źródło
Chciałbym dodać inny punkt widzenia w celu rozwiązania tego problemu, zwłaszcza jeśli masz do usunięcia niewielką liczbę kolumn.
Możesz użyć narzędzia DB, takiego jak MySQL Workbench , aby wygenerować dla siebie instrukcję select, więc musisz ręcznie usunąć te kolumny z wygenerowanej instrukcji i skopiować ją do skryptu SQL.
W MySQL Workbench sposobem na jego wygenerowanie jest:
Kliknij prawym przyciskiem myszy tabelę -> wyślij do edytora Sql -> Wybierz wszystko.
źródło
Przyjęta odpowiedź ma kilka wad.
Wszystkie te problemy można przezwyciężyć, po prostu włączając backticks w
SEPARATOR
forGROUP_CONCAT
i używającWHERE
warunku zamiastREPLACE()
. Dla moich celów (i wyobrażam sobie wielu innych) chciałem, aby nazwy kolumn były zwracane w tej samej kolejności, w jakiej pojawiają się w samej tabeli. Aby to osiągnąć, używamy wyraźnejORDER BY
klauzuli wewnątrzGROUP_CONCAT()
funkcji:źródło
Mam sugestię, ale nie rozwiązanie. Jeśli niektóre kolumny mają większe zestawy danych, spróbuj wykonać następujące czynności
źródło
Jestem dość późno, próbując znaleźć odpowiedź na to pytanie. Mówię to w ten sposób, że zawsze tak robiłem. Szczerze mówiąc, jest on 100 razy lepszy i ładniejszy niż najlepsza odpowiedź, mam tylko nadzieję, że ktoś to zobaczy. I uznaj to za przydatne
źródło
SELECT
tu żadnej instrukcji - słowo nie pojawia się ani razu.Wybierz * to antipattern SQL. Nie należy go używać w kodzie produkcyjnym z wielu powodów, w tym:
Przetwarzanie zajmuje trochę dłużej. Kiedy rzeczy są uruchamiane miliony razy, te małe kawałki mogą mieć znaczenie. Powolna baza danych, w której powolność jest powodowana przez tego rodzaju niechlujne kodowanie, jest najtrudniejsza do dostrojenia.
Oznacza to, że prawdopodobnie wysyłasz więcej danych niż potrzebujesz, co powoduje wąskie gardła zarówno serwera, jak i sieci. Jeśli masz połączenie wewnętrzne, szanse na wysłanie większej liczby danych niż potrzebujesz to 100%.
Powoduje to problemy konserwacyjne, zwłaszcza gdy dodałeś nowe kolumny, których nie chcesz widzieć wszędzie. Ponadto, jeśli masz nową kolumnę, może być konieczne zrobienie czegoś z interfejsem, aby ustalić, co zrobić z tą kolumną.
Może to popsuć widoki (wiem, że jest to prawdą na serwerze SQl, może być lub nie być prawdą w mysql).
Jeśli ktoś jest wystarczająco głupi, aby odbudować tabele z kolumnami w innej kolejności (czego nie powinieneś robić, ale zdarza się to cały czas), wszelkiego rodzaju kod może się zepsuć. W szczególności kod dla wstawki, na przykład, gdy nagle wpisujesz miasto w polu adres_3, ponieważ nie określono, baza danych może przechodzić tylko w kolejności kolumn. Jest to wystarczająco złe, gdy zmieniają się typy danych, ale gorzej, gdy zamienione kolumny mają ten sam typ danych, ponieważ można czasem wstawić złe dane, które są bałaganem do wyczyszczenia. Musisz dbać o integralność danych.
Jeśli zostanie zastosowany we wstawce, spowoduje uszkodzenie wkładki, jeśli nowa kolumna zostanie dodana do jednej tabeli, ale nie do drugiej.
Może to spowodować uszkodzenie wyzwalaczy. Problemy z wyzwalaczem mogą być trudne do zdiagnozowania.
Zsumuj to w stosunku do czasu potrzebnego na dodanie nazw kolumn (do cholery możesz nawet mieć interfejs, który pozwala ci przeciągać nazwy kolumn (wiem, że robię to w SQL Server, założę się, że jest jakiś sposób na zrób to narzędzie, którego używasz do pisania zapytań mysql.) Zobaczmy: „Mogę powodować problemy z konserwacją, mogę powodować problemy z wydajnością i problemy z integralnością danych, ale hej, zaoszczędziłem pięć minut na programowaniu”. w konkretnych kolumnach, które chcesz.
Sugeruję także przeczytanie tej książki: 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 i słowa kluczowe = sql + antipatterns
źródło