Chọn tất cả các cột ngoại trừ một cột trong MySQL?


365

Tôi đang cố gắng sử dụng một câu lệnh chọn để lấy tất cả các cột từ một bảng MySQL nhất định trừ một cột. Có một cách đơn giản để làm điều này?

EDIT: Có 53 cột trong bảng này (KHÔNG PHẢI THIẾT KẾ CỦA TÔI)


6
53 cột? Tôi sẽ gắn bó với CHỌN * như Thomas đề xuất trong trường hợp đó ... trừ khi cột bổ sung đó có một lượng dữ liệu khổng lồ không mong muốn để truy xuất ...?
Mike Stone

Ngoại trừ một colum ... Tôi cho rằng bạn biết cái nào nên được bỏ qua, do đó, thông tin chính là thông tin.
Alfabravo

Kiểm tra câu trả lời này nó làm những gì bạn muốn làm!
donL

Cột dữ liệu lớn là một vấn đề thực sự khi dữ liệu địa lý được tổ chức. Các cột có thể có nhiều megabyte. Chúng hoạt động tốt ở những mệnh đề để tìm hàng, nhưng bạn thường không muốn dữ liệu đó trong kết quả.
Jason

Một cách sử dụng phổ biến cho việc này là để loại trừ cột ID tăng tự động. Ví dụ: để chọn dữ liệu được chèn vào một bảng khác, có ID riêng.
ToolmakerSteve

Câu trả lời:


222

Trên thực tế có một cách, bạn cần phải có quyền tất nhiên để làm điều này ...

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;

Thay thế <table>, <database> and <columns_to_omit>


20
Hãy cẩn thận: Các truy vấn Information_SCHema có hiệu suất khá kém, vì vậy hãy cẩn thận loại truy vấn này không nằm trong đường dẫn quan trọng cho bất cứ điều gì.
Bill Karwin

9
Giống như @Jan Koritak đã nói bên dưới, câu trả lời này không thực sự hoạt động nếu các cột của tiêu đề mà bạn muốn xóa cũng là một chuỗi con của tiêu đề cho bất kỳ cột nào bạn muốn giữ. Có một câu trả lời tốt hơn tương tự như điều này có thể được tìm thấy ở đây .
donL

8
Đây là cách tồi tệ hơn là chỉ định các cột là một thực tiễn tốt nhất được biết đến.
HLGEM

3
Điều này không hoạt động nếu có khoảng trắng trong tên cột. Nó nên được cập nhật để luôn bao quanh các tên trong backticks<column_name>
adamF

3
Điều này cũng sẽ không hoạt động nếu cột bị bỏ qua là cột cuối cùng được liệt kê trong cấu trúc bảng (vì thay thế sẽ không khớp với trạng thái hôn mê).
Vincent Pazeller 17/2/2015

61

Trong định nghĩa mysql (thủ công) không có điều đó. Nhưng nếu bạn có số lượng cột thực sự lớn col1, ... ,, col100thì những điều sau đây có thể hữu ích:

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;

4
Đã cho tôi thông báo lỗi ở bước thứ 3: "Đếm cột không khớp với giá trị đếm ở hàng 1". Vì vậy, tôi đã thay đổi bước 2 thành "CẬP NHẬT temp_tb SET id = NULL" và sau đó nó hoạt động.
oyvey

1
Ok, cái này hoạt động. Nhưng khi tôi chạy lại truy vấn này, nó lại báo lỗi, temp_tb đã tồn tại. Bao nhiêu thời gian temp_tb trong bộ nhớ? Xin lỗi nếu đó là một câu hỏi ngu ngốc. PS nêu lên câu trả lời của bạn.
Karan

2
@Karan Để chạy truy vấn này nhiều lần, hãy thêm một lệnh khác vào đầu:DROP TABLE IF EXISTS temp_tb;
gregn3

1
@Karan Để chỉ định công cụ bộ nhớ, sử dụng lệnh: CREATE TEMPORARY TABLE temp_tb ENGINE=MEMORY (SELECT * FROM orig_tb); nếu không, nó được lưu vào đĩa theo mặc định và tồn tại khi máy chủ khởi động lại. ( cảm ơn )
gregn3

Câu trả lời tuyệt vời. Để bỏ nhiều cột , hãy tham khảo câu trả lời này .
S3DEV

45

Một View sẽ hoạt động tốt hơn trong trường hợp này?

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

15
HAHA! Ừ chắc chắn. Bây giờ làm thế nào để bạn xây dựng chế độ xem để bao gồm tất cả NHƯNG một trong các cột. Tôi nghĩ rằng bạn thấy làm thế nào điều này đặt ra câu hỏi ban đầu. Trong thực tế, tôi đã tìm thấy chủ đề này một cách cụ thể vì tôi muốn tạo một chế độ xem loại trừ các cột nhất định mà không bị buộc phải liệt kê rõ ràng tất cả các cột còn lại trong định nghĩa chế độ xem.
Chris Nadovich

31

Bạn có thể làm:

SELECT column1, column2, column4 FROM table WHERE whatever

mà không nhận được cột3, mặc dù có lẽ bạn đang tìm kiếm một giải pháp tổng quát hơn?


3
Hầu hết các câu trả lời được xếp hạng cao hơn chủ yếu chỉ là tìm cách tạo truy vấn chính xác này mà không cần nhập bằng tay
mehtunguh

5
Trên thực tế, vì lý do bảo trì, rất hữu ích khi có một loại truy vấn "mọi thứ trừ". Mặt khác, danh sách trường rõ ràng phải được cập nhật nếu các trường mới được thêm vào sau.
leiavoia

1
@lev, điều đó đúng và HỌ NÊN !!! BEcasue bạn không biết nếu bạn muốn có bất kỳ cột nào trong tương lai (chúng có thể là cột dữ liệu meta hoặc cột không áp dụng cho một màn hình cụ thể). Bạn không; muốn làm hại hiệu suất bằng cách trả lại nhiều hơn mức bạn cần (điều này đúng 100% khi bạn có một phép nối bên trong) Tôi khuyên bạn nên đọc một số lý do tại sao chọn * là một phản đề SQL.
HLGEM

26
Các trạng thái OP có> 50 cột nên điều này khá không thực tế.
tám

1
@HLGEM Không thực sự, tôi muốn chọn tất cả các cột mà không duy trì truy vấn mỗi khi tôi thêm một cột mới, ngoại trừ một trong số chúng, và điều này sẽ không hoạt động trong trường hợp của tôi. Nhưng dù sao tôi cũng đã áp dụng giải pháp của Sean O cho chính mình
OverCoder

26

Nếu bạn đang tìm cách loại trừ giá trị của một trường, ví dụ: đối với các vấn đề bảo mật / thông tin nhạy cảm, bạn có thể truy xuất cột đó dưới dạng null.

ví dụ

SELECT *, NULL AS salary FROM users

13
Tại sao? Nó không hoạt động. Nếu bạn có mức lương của cột, truy vấn này sẽ kết thúc với kết quả có hai cột có tên là lương, một cột có giá trị rỗng và một cột có mức lương thực tế.
Myforwik

4
@Myforwik Truy vấn này thực sự thêm một salarycột thứ hai . Nhưng vì nó được truy xuất sau dấu *, nó ghi đè lên bản gốc. Nó không đẹp, nhưng nó hoạt động.
Sean O

67
SQL luôn cho phép các tên cột trùng lặp trong tập kết quả. Nếu bạn muốn nó hoạt động, bạn cần chạy nó với một ứng dụng khách không hỗ trợ các bản sao ưu tiên cho bản sao cuối cùng. Máy khách dòng lệnh chính thức hỗ trợ các bản sao. HeidiSQL cũng hỗ trợ họ. SQL Fiddle không, nhưng hiển thị bản dupe đầu tiên , không kéo dài. Tóm lại: điều này không hoạt động .
Álvaro González

9
Tất nhiên là nó không hoạt động. Đây là ví dụ tuyệt vời về lý do tại sao bạn nên kiểm tra câu trả lời của mình trong chính mysql, thay vì thông qua các thư viện nói chuyện với mysql.
Myforwik

8
@SeanO, @ Alastair, @ Mọi người, Không ghi đè. Máy chủ vẫn trả về dữ liệu nhạy cảm.
Pacerier

22

Theo hiểu biết tốt nhất của tôi, không có. Bạn có thể làm một cái gì đó như:

SELECT col1, col2, col3, col4 FROM tbl

và tự chọn các cột bạn muốn. Tuy nhiên, nếu bạn muốn có nhiều cột, thì bạn có thể chỉ muốn thực hiện:

SELECT * FROM tbl 

và chỉ cần bỏ qua những gì bạn không muốn.

Trong trường hợp cụ thể của bạn, tôi sẽ đề nghị:

SELECT * FROM tbl

trừ khi bạn chỉ muốn một vài cột. Nếu bạn chỉ muốn bốn cột, thì:

SELECT col3, col6, col45, col 52 FROM tbl

sẽ ổn, nhưng nếu bạn muốn 50 cột, thì bất kỳ mã nào làm cho truy vấn sẽ trở nên (quá?) khó đọc.


3
Chọn * là một lựa chọn kém luôn. Đừng giới thiệu nó. Đọc về lý do tại sao nó là một Antipotype.
HLGEM

18

Trong khi thử các giải pháp của @Mahomedalid và @Junaid, tôi thấy có một vấn đề. Vì vậy, nghĩ về việc chia sẻ nó. Nếu tên cột có dấu cách hoặc dấu gạch nối như đăng ký thì truy vấn sẽ thất bại. Cách giải quyết đơn giản là sử dụng backtick xung quanh tên cột. Các truy vấn sửa đổi dưới đây

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;

11

Nếu cột mà bạn không muốn chọn có một lượng lớn dữ liệu trong đó và bạn không muốn đưa nó vào do vấn đề tốc độ và bạn thường xuyên chọn các cột khác, tôi sẽ đề nghị bạn tạo một bảng mới với một trường mà bạn thường không chọn bằng một phím cho bảng gốc và xóa trường khỏi bảng gốc. Tham gia các bảng khi trường đó thực sự cần thiết.



8

Vấn đề chính của tôi là nhiều cột tôi nhận được khi tham gia các bảng. Mặc dù đây không phải là câu trả lời cho câu hỏi của bạn (cách chọn tất cả trừ một số cột nhất định từ một bảng), tôi nghĩ điều đáng nói là bạn có thể chỉ định để lấy tất cả các cột từ một bảng cụ thể, thay vì chỉ xác định .table.

Đây là một ví dụ về cách điều này có thể rất hữu ích:

chọn người dùng. *, phone.meta_value làm điện thoại, zipcode.meta_value làm zipcode

từ người dùng

còn lại tham gia user_meta như điện thoại
bật ((users.user_id = phone.user_id) VÀ (phone.meta_key = 'phone'))

còn lại tham gia user_meta dưới dạng mã zip
bật ((users.user_id = zipcode.user_id) VÀ (zipcode.meta_key = 'zipcode'))

Kết quả là tất cả các cột từ bảng người dùng và hai cột bổ sung được nối từ bảng meta.


2
cảm ơn bạn, tôi cần chọn tất cả các cột của bảng đầu tiên và chỉ có một trường từ bảng thứ hai tham gia và câu trả lời của bạn đã giúp tôi.
mohammad falahat

5

Tôi thích câu trả lời từ @Mahomedalidbên cạnh thực tế này được thông báo trong nhận xét từ @Bill Karwin. Vấn đề có thể xảy ra @Jan Koritaklà sự thật tôi đã đối mặt với điều đó nhưng tôi đã tìm ra một mẹo cho điều đó và chỉ muốn chia sẻ nó ở đây cho bất cứ ai phải đối mặt với vấn đề này.

chúng ta có thể thay thế hàm REPLACE bằng mệnh đề where trong truy vấn con của câu lệnh Prepared như thế này:

Sử dụng tên bảng và cột của tôi

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;

Vì vậy, điều này sẽ chỉ loại trừ trường idnhưng khôngcompany_id


4

Đó là một thực hành tốt để xác định các cột mà bạn đang truy vấn ngay cả khi bạn truy vấn tất cả các cột.

Vì vậy, tôi sẽ đề nghị bạn viết tên của từng cột trong câu lệnh (không bao gồm cột bạn không muốn).

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

FROM table

Nó hoạt động như một hợp đồng với mã và khi nhìn vào truy vấn, bạn biết chính xác dữ liệu nào bạn có thể trích xuất từ ​​nó mà không cần nhìn vào lược đồ của bảng.
mbillard

6
@kodecraft: Đó là một thực tiễn tốt cho cùng một lý do rằng đó là cách thực hành tốt để luôn trả lại cùng loại từ một chức năng (ngay cả khi bạn làm việc trong một ngôn ngữ không được thi hành). Về cơ bản chỉ là Nguyên tắc bất ngờ tối thiểu.
Daniel Pryden

4

Cứ làm đi

SELECT * FROM table WHERE whatever

Sau đó thả cột trong ngôn ngữ lập trình yêu thích của bạn: php

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

6
Trừ khi cột bạn muốn loại trừ là một BLOB lớn hoặc một cái gì đó.
Bill Karwin

1
Điều này là xấu nếu bạn đang cố gắng tránh dữ liệu lãng phí.
Kristopher Ives

1 cột từ 53 không nên làm cho bất kỳ sự khác biệt. Nếu nó có lẽ là một thiết kế xấu.
Petr Peller

1
SElect * là một antipotype SQL và không bao giờ được sử dụng trong mã sản xuất.
HLGEM

1
Tôi không đồng ý rằng CHỌN * là một loại chống mẫu nên "không bao giờ" được sử dụng trong mã sản xuất. Rõ ràng hơn là bạn đã truy xuất tất cả các cột của mình - so với việc tham chiếu chéo một danh sách dài các cột có thể hoặc không, trên thực tế là tất cả các trường. Nó cũng, rất rõ ràng, nhanh hơn để mã hóa, cho đến nay. Và có rất nhiều trường hợp trong đó các trường của bảng sẽ tương ứng chính xác với các trường trong dạng xem hoặc biểu mẫu.
Geoff Kendall

4

Tôi đồng ý với giải pháp "đơn giản" trong việc liệt kê tất cả các cột, nhưng điều này có thể gây gánh nặng và lỗi chính tả có thể gây lãng phí nhiều thời gian. Tôi sử dụng hàm "getTableColumns" để lấy tên của các cột phù hợp để dán vào truy vấn. Sau đó, tất cả những gì tôi cần làm là xóa những cái tôi không muốn.

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;

Kết quả của bạn trả về một chuỗi được phân cách bằng dấu phẩy, ví dụ ...

col1, col2, col3, col4, ... col53



4

Vâng, mặc dù nó có thể là I / O cao tùy thuộc vào bảng ở đây là một cách giải quyết tôi tìm thấy cho nó.

SELECT *
INTO #temp
FROM table

ALTER TABLE #temp DROP COlUMN column_name

SELECT *
FROM #temp

Điều này sẽ rất chậm đối với bất kỳ bảng có kích thước vừa phải.
Joel

3

Tôi đồng ý rằng nó không đủ để Select *, nếu cái mà bạn không cần, như đã đề cập ở nơi khác, là một BLOB, bạn không muốn có cái đầu bò đó.

Tôi sẽ tạo một khung nhìn với dữ liệu cần thiết, sau đó bạn có thể Select *thoải mái - nếu phần mềm cơ sở dữ liệu hỗ trợ chúng. Khác, đặt dữ liệu lớn trong một bảng khác.


3

Lúc đầu tôi nghĩ bạn có thể sử dụng các biểu thức thông thường, nhưng vì tôi đã đọc tài liệu MYSQL nên dường như bạn không thể. Nếu tôi là bạn, tôi sẽ sử dụng ngôn ngữ khác (như PHP) để tạo danh sách các cột bạn muốn lấy, lưu trữ dưới dạng chuỗi và sau đó sử dụng ngôn ngữ đó để tạo SQL.


3

Tôi cũng muốn điều này vì vậy tôi đã tạo ra một chức năng thay thế.

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)."`";
    }
}

Vì vậy, cách nó hoạt động là bạn nhập vào bảng, sau đó một cột bạn không muốn hoặc như trong một mảng: mảng ("id", "name", "anythingcolumn")

Vì vậy, trong lựa chọn bạn có thể sử dụng nó như thế này:

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

hoặc là

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

3

Tôi đồng ý với câu trả lời của @ Mahomedalid, nhưng tôi không muốn làm điều gì đó như một tuyên bố đã chuẩn bị và tôi không muốn gõ tất cả các lĩnh vực, vì vậy những gì tôi có là một giải pháp ngớ ngẩn.

Đi đến bảng trong phpmyadmin-> sql-> select, nó bỏ truy vấn: sao chép, thay thế và thực hiện! :)


2

Mặc dù tôi đồng ý với câu trả lời của Thomas (+1;)), tôi muốn thêm lời cảnh báo rằng tôi sẽ giả sử cột mà bạn không muốn chứa hầu như không có dữ liệu. Nếu nó chứa số lượng lớn văn bản, xml hoặc các đốm nhị phân, thì hãy dành thời gian để chọn từng cột riêng lẻ. Hiệu suất của bạn sẽ bị khác. Chúc mừng!


2

Câu trả lời được đăng bởi Mahomedalid có một vấn đề nhỏ:

Bên trong mã chức năng thay thế đã thay thế " <columns_to_delete>," bằng "", sự thay thế này có vấn đề nếu trường thay thế là trường cuối cùng trong chuỗi concat do cái cuối cùng không có dấu phẩy "," và không bị xóa khỏi chuỗi.

Đề nghị của tôi:

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>');

Thay thế <table>, <database>và '

Cột bị xóa được thay thế bằng chuỗi "FIELD_REMOVED" trong trường hợp của tôi, điều này hoạt động vì tôi đang cố gắng bảo vệ bộ nhớ. (Trường tôi đã xóa là BLOB khoảng 1MB)


2

Dựa trên câu trả lời @Mahomedalid, tôi đã thực hiện một số cải tiến để hỗ trợ "chọn tất cả các cột ngoại trừ một số cột trong 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;

Nếu bạn có nhiều cols, hãy sử dụng sql này để thay đổi group_concat_max_len

SET @@group_concat_max_len = 2048;

2

Có thể tôi có một giải pháp cho sự khác biệt được chỉ ra của Jan Koritak

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' );

Bàn :

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

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

Kết quả truy vấn:

'SELECT name_eid,sal FROM employee'

1

Nếu nó luôn luôn là cùng một cột, thì bạn có thể tạo chế độ xem không có cột đó.

Mặt khác, không, tôi không nghĩ vậy.


1

Bạn có thể sử dụng SQL để tạo SQL nếu bạn thích và đánh giá SQL mà nó tạo ra. Đây là một giải pháp chung vì nó trích xuất các tên cột từ lược đồ thông tin. Đây là một ví dụ từ dòng lệnh Unix.

Thay thế

  • MYSQL với lệnh mysql của bạn
  • BẢNG với tên bảng
  • LOẠI TRỪ với tên trường bị loại trừ
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

Bạn thực sự sẽ chỉ cần trích xuất các tên cột theo cách này chỉ một lần để xây dựng danh sách cột loại trừ cột đó, và sau đó chỉ cần sử dụng truy vấn bạn đã xây dựng.

Vì vậy, một cái gì đó như:

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)

Bây giờ bạn có thể sử dụng lại $column_listchuỗi trong các truy vấn bạn xây dựng.


1

Tôi muốn thêm một quan điểm khác để giải quyết vấn đề này, đặc biệt nếu bạn có một số lượng nhỏ cột cần loại bỏ.

Bạn có thể sử dụng một công cụ DB như MySQL Workbench để tạo câu lệnh chọn cho bạn, vì vậy bạn chỉ cần xóa thủ công các cột đó cho câu lệnh được tạo và sao chép nó vào tập lệnh SQL của bạn.

Trong MySQL Workbench cách để tạo ra nó là:

Nhấp chuột phải vào bảng -> gửi tới Sql Editor -> Chọn Tất cả Tuyên bố.


1

Câu trả lời được chấp nhận có một số thiếu sót.

  • Nó không thành công khi tên bảng hoặc cột yêu cầu backticks
  • Không thành công nếu cột bạn muốn bỏ qua cuối cùng trong danh sách
  • Nó yêu cầu liệt kê tên bảng hai lần (một lần cho lựa chọn và một lần khác cho văn bản truy vấn) không cần thiết và không cần thiết
  • Nó có khả năng trả về tên cột theo thứ tự sai

Tất cả những vấn đề này có thể được khắc phục bằng cách đơn giản bao gồm các backticks SEPARATORcho bạn GROUP_CONCATvà sử dụng một WHEREđiều kiện thay vì REPLACE(). Đối với mục đích của tôi (và tôi tưởng tượng nhiều người khác), tôi muốn các tên cột được trả về theo thứ tự giống như chúng xuất hiện trong bảng. Để đạt được điều này, ở đây chúng tôi sử dụng một ORDER BYmệnh đề rõ ràng bên trong GROUP_CONCAT()hàm:

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';

0

Tôi có một đề nghị nhưng không phải là một giải pháp. Nếu một số cột của bạn có bộ dữ liệu lớn hơn thì bạn nên thử làm theo

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

-1

Tôi khá muộn khi đưa ra câu trả lời cho điều này, đây là cách tôi luôn làm và thẳng thắn, nó tốt hơn và gọn gàng hơn gấp 100 lần so với câu trả lời hay nhất, tôi chỉ hy vọng ai đó sẽ nhìn thấy nó. Và thấy nó hữu ích

    //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]);

Nó có thể gọn gàng, nhưng nó không trả lời câu hỏi: anh ấy đã không hỏi về php và bạn không đưa ra một tuyên bố chọn lọc hoặc kết quả của những gì anh ấy muốn, mà chỉ là một mảng php chứa các cột anh ấy muốn.
gou1

2
Cẩu1. Đây không phải là mã SQL và không có SELECTtuyên bố nào ở đây. Từ này thậm chí không xuất hiện một lần.
Frungi

Điều này chỉ gọn gàng hơn ở mức độ (a) bạn cảm thấy thoải mái với PHP hơn SQL hoặc (b) bạn muốn trải rộng mã của mình qua nhiều dòng để dễ đọc. Tôi sẽ thừa nhận điểm (b). Cách tiếp cận của bạn cũng sẽ ít hiệu quả hơn, mặc dù sự khác biệt sẽ là nhỏ trong nhiều trường hợp sử dụng. Cũng xem các bình luận khác về câu hỏi của bạn. Không đáng để hét lên, vì vậy đề nghị bạn loại bỏ nhận xét không phù hợp của bạn khỏi câu hỏi ban đầu.
mc0e

-5

Chọn * là một phản mẫu SQL. Nó không nên được sử dụng trong mã sản xuất vì nhiều lý do bao gồm:

Phải mất một chút thời gian dài để xử lý. Khi mọi thứ được chạy hàng triệu lần, những bit nhỏ đó có thể quan trọng. Một cơ sở dữ liệu chậm trong đó sự chậm chạp được gây ra bởi loại mã hóa cẩu thả này là loại khó nhất để điều chỉnh hiệu suất.

Điều đó có nghĩa là bạn có thể đang gửi nhiều dữ liệu hơn mức bạn cần, điều này gây ra tắc nghẽn cả máy chủ và mạng. Nếu bạn có một tham gia bên trong, cơ hội gửi nhiều dữ liệu hơn bạn cần là 100%.

Nó gây ra vấn đề bảo trì đặc biệt là khi bạn đã thêm các cột mới mà bạn không muốn thấy ở mọi nơi. Hơn nữa nếu bạn có một cột mới, bạn có thể cần phải làm gì đó với giao diện để xác định phải làm gì với cột đó.

Nó có thể phá vỡ các khung nhìn (Tôi biết điều này đúng trong máy chủ SQl, nó có thể đúng hoặc không đúng trong mysql).

Nếu ai đó đủ ngớ ngẩn để xây dựng lại các bảng với các cột theo thứ tự khác nhau (điều bạn không nên làm nhưng nó xảy ra mọi lúc), tất cả các loại mã có thể bị phá vỡ. Mã đặc biệt cho một chèn chẳng hạn, trong đó đột nhiên bạn đặt thành phố vào trường address_3 vì không chỉ định, cơ sở dữ liệu chỉ có thể đi theo thứ tự của các cột. Điều này đủ tệ khi các kiểu dữ liệu thay đổi nhưng tệ hơn khi các cột được hoán đổi có cùng kiểu dữ liệu vì bạn đôi khi có thể chèn dữ liệu xấu là một mớ hỗn độn để dọn dẹp. Bạn cần quan tâm đến tính toàn vẹn dữ liệu.

Nếu nó được sử dụng trong một chèn, nó sẽ phá vỡ chèn nếu một cột mới được thêm vào trong một bảng nhưng không phải là một bảng khác.

Nó có thể phá vỡ các kích hoạt. Vấn đề kích hoạt có thể khó chẩn đoán.

Thêm tất cả điều này vào thời gian cần thêm vào các tên cột (bạn thậm chí có thể có một giao diện cho phép bạn kéo qua các tên cột (Tôi biết tôi làm trong SQL Server, tôi cá là có một số cách để làm điều này là một số công cụ bạn sử dụng để viết các truy vấn mysql.) Hãy xem, "Tôi có thể gây ra sự cố bảo trì, tôi có thể gây ra vấn đề về hiệu suất và tôi có thể gây ra sự cố toàn vẹn dữ liệu, nhưng tôi đã tiết kiệm được năm phút của thời gian phát triển." trong các cột cụ thể mà bạn muốn.

Tôi cũng đề nghị bạn đọc cuốn sách này: http://www.amazon.com 1 & Keywords = sql + antipotypes

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.