MySQL में एक को छोड़कर सभी कॉलम चुनें?


365

मैं एक को छोड़कर एक निश्चित MySQL तालिका से सभी कॉलम प्राप्त करने के लिए एक चयन कथन का उपयोग करने की कोशिश कर रहा हूं। क्या ऐसा करने के लिए एक सरल तरीका है?

संपादित करें: इस तालिका में 53 स्तंभ हैं (मेरा विवरण नहीं)


6
53 कॉलम? मैं SELECT * के साथ रहना चाहूंगा क्योंकि थॉमस उस मामले में सुझाव देता है ... जब तक कि अतिरिक्त कॉलम में डेटा की एक बड़ी मात्रा नहीं है जो पुनः प्राप्त करने के लिए अवांछनीय होगा ...?
माइक स्टोन

एक कोलम को छोड़कर ... मुझे लगता है कि आप जानते हैं कि किसको अनदेखा किया जाना चाहिए, इसलिए INFORMATION_SCHEMA.columns का तरीका है।
अल्फ्रावो

इस उत्तर की जाँच करें कि यह वही करता है जो आप करना चाहते हैं!
donL

भौगोलिक डेटा आयोजित होने पर बड़ा डेटा कॉलम एक वास्तविक मुद्दा है। कॉलम आकार में कई मेगाबाइट हो सकते हैं। वे पंक्तियों को खोजने के लिए जहां क्लॉस में अच्छी तरह से काम करते हैं, लेकिन आप अक्सर परिणामों में उस डेटा को नहीं चाहते हैं।
जेसन

इसके लिए एक सामान्य उपयोग ऑटो-इंक्रीमेंट आईडी कॉलम को बाहर करना है। उदाहरण के लिए, किसी भिन्न तालिका में सम्मिलित किए जाने वाले डेटा का चयन करने के लिए, जिसकी अपनी आईडी है।
टूलमेकरसेव

जवाबों:


222

वास्तव में एक तरीका है, आपको ऐसा करने के लिए पाठ्यक्रम की अनुमति की आवश्यकता है ...

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>


20
चेतावनी: INFORMATION_SCHEMA प्रश्नों का प्रदर्शन बहुत खराब है, इसलिए सावधान रहें कि इस प्रकार की क्वेरी किसी भी चीज़ के लिए महत्वपूर्ण पथ में नहीं है।
बिल करविन

9
जैसे @Jan Koritak ने नीचे कहा, यह उत्तर वास्तव में काम नहीं करता है यदि आप जिस शीर्षक के कॉलम को हटाना चाहते हैं वह शीर्षक के उप-स्ट्रिंग भी हैं जिन्हें आप रखना चाहते हैं। एक बेहतर उत्तर है जो इस के समान है जो यहां पाया जा सकता है
donL

8
यह केवल उन कॉलमों को निर्दिष्ट करने की तुलना में बदतर है जो एक ज्ञात सर्वोत्तम अभ्यास है।
HLGEM

3
यदि स्तंभ नाम में रिक्त स्थान हैं, तो यह काम नहीं करता है। यह हमेशा <column_name>
बैकटिक्स

3
यह भी काम नहीं करेगा यदि स्तंभ को नजरअंदाज किया जाए तो तालिका संरचना में सूचीबद्ध अंतिम एक है (क्योंकि प्रतिस्थापित ट्रेलिंग कॉमेडी से मेल नहीं खाएगा)।
विन्सेन्ट पैज़ेलर

61

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;

4
मुझे तीसरे चरण पर त्रुटि संदेश दिया: "कॉलम संख्या पंक्ति 1 पर मूल्य गणना से मेल नहीं खाती"। इसलिए मैंने चरण 2 को "UPDATE temp_tb SET id = NULL" में बदल दिया और फिर इसने काम किया।
veyॉयवे

1
ठीक है, यह काम करता है। लेकिन जब मैं इस क्वेरी को फिर से चलाता हूं, तो यह मुझे एक त्रुटि देता है, कि, temp_tb पहले से मौजूद है। मेमोरी में कितने समय के लिए temp_tb है? अगर यह एक बेवकूफी भरा सवाल है तो माफी। पीएस ने आपके जवाब को गलत बताया।
करण

2
@ करन इस क्वेरी को बार-बार चलाने के लिए, शुरुआत में एक और कमांड जोड़ें:DROP TABLE IF EXISTS temp_tb;
gregn3

1
@Karan मेमोरी इंजन को निर्दिष्ट करने के लिए, कमांड का उपयोग करें: CREATE TEMPORARY TABLE temp_tb ENGINE=MEMORY (SELECT * FROM orig_tb); अन्यथा, यह डिफ़ॉल्ट रूप से डिस्क पर सहेजा जाता है, और सर्वर पुनरारंभ होता है। ( धन्यवाद )
gregn3

बहुत बढ़िया जवाब। कई कॉलम छोड़ने के लिए , इस उत्तर को देखें ।
S3DEV

45

क्या इस मामले में एक दृश्य बेहतर काम करेगा?

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

15
हा हा हा! हां यकीनन। अब आप सभी स्तंभों में से एक को शामिल करने के लिए दृश्य का निर्माण कैसे करते हैं। मुझे लगता है कि आप देखते हैं कि यह मूल प्रश्न को कैसे बताता है। वास्तव में, मुझे यह धागा विशेष रूप से इसलिए मिला क्योंकि मैं एक ऐसा दृश्य बनाना चाहता था जिसमें दृश्य परिभाषा में स्पष्ट रूप से शेष सभी स्तंभों को सूचीबद्ध करने के लिए मजबूर किए बिना कुछ स्तंभों को छोड़ दिया जाए।
क्रिस नदोविच

31

तुम कर सकते हो:

SELECT column1, column2, column4 FROM table WHERE whatever

बिना कॉलम 3 प्राप्त किए, हालांकि शायद आप एक अधिक सामान्य समाधान की तलाश में थे?


3
उच्च श्रेणी के उत्तर में से ज्यादातर केवल हाथ से टाइप किए बिना ही इस सटीक क्वेरी को उत्पन्न करने के तरीके खोज रहे हैं
mehtunguh

5
दरअसल, रखरखाव कारणों के लिए, "क्वेरी को छोड़कर" सब कुछ होना उपयोगी है। यदि बाद में नए फ़ील्ड जोड़े जाते हैं, तो स्पष्ट फ़ील्ड सूचियों को अपडेट किया जाना चाहिए।
लेवियावो

1
@ ऊँचाई, यह सही है और उनका होना चाहिए !!! यदि आप भविष्य में कोई कॉलम रखना चाहते हैं तो आप नहीं जानते (वे मेटा डेटा कॉलम हो सकते हैं या जो किसी विशेष स्क्रीन पर लागू नहीं होते हैं)। तुम नहीं; अपनी आवश्यकता से अधिक रिटर्न करके प्रदर्शन को नुकसान पहुंचाना चाहते हैं (जो कि उस समय का 100% सच है जब आपके पास एक आंतरिक जुड़ाव होता है) मेरा सुझाव है कि आप कुछ पढ़ने का चयन करें कि क्यों * एक SQL एंटीपैटर्न है।
एचएलजीईएम

26
ओपी में कहा गया है कि> 50 कॉलम हैं इसलिए यह अव्यावहारिक है।
अगस्तुर

1
@ एचएलजीईएम वास्तव में नहीं, मैं हर बार जब मैं एक नया कॉलम जोड़ता हूं, तो उनमें से एक को छोड़कर, सभी कॉलम का चयन करना चाहता था, और यह केवल मेरे मामले में काम नहीं करेगा। लेकिन वैसे भी मैंने अपने लिए सीन ओ के समाधान को लागू किया
ओवरकोडर

26

यदि आप किसी क्षेत्र के मान को बाहर करना चाह रहे हैं, जैसे सुरक्षा चिंताओं / संवेदनशील जानकारी के लिए, तो आप उस कॉलम को शून्य मान सकते हैं।

जैसे

SELECT *, NULL AS salary FROM users

13
क्यों? यह काम नहीं करता है। यदि आपके पास एक स्तंभ वेतन है, तो यह क्वेरी केवल दो कॉलम नाम वेतन, एक नल से भरा और वास्तविक वेतन के साथ परिणाम के साथ समाप्त होगी।
Myforwik

4
@Myforwik यह क्वेरी वास्तव में एक दूसरा salaryकॉलम जोड़ती है । लेकिन चूंकि यह * के बाद पुनः प्राप्त होता है, इसलिए यह मूल को अधिलेखित कर देता है। यह सुंदर नहीं है, लेकिन यह काम करता है।
शॉन ओ

67
SQL ने हमेशा परिणाम-सेट में डुप्लिकेट कॉलम नामों की अनुमति दी है। यदि आप चाहते हैं कि यह काम करने के लिए आपको इसे एक क्लाइंट एप्लिकेशन के साथ चलाने की आवश्यकता है जो ड्यूप्स का समर्थन नहीं करता है और अंतिम डुबकी को प्राथमिकता देता है। आधिकारिक कमांड-लाइन क्लाइंट डुप्सेस का समर्थन करता है। HeidiSQL उन्हें भी समर्थन करता है। एसक्यूएल फिडल नहीं है, लेकिन पहले डुबकी प्रदर्शित करता है , पिछले नहीं। योग करने के लिए: यह काम नहीं करता है
अल्वारो गोंजालेज

9
बेशक यह काम नहीं करता है। यह इस बात का बहुत अच्छा उदाहरण है कि आपको mysql में अपने उत्तरों का परीक्षण करना चाहिए, बजाय पुस्तकालयों के माध्यम से जो कि mysql से बात करते हैं।
Myforwik

8
@ सीनो, @ एलेस्टेयर, @ सब, ओवरराइड नहीं करता। सर्वर अभी भी संवेदनशील डेटा लौटाता है।
पचेरियर

22

मेरे ज्ञान का सबसे अच्छा करने के लिए, वहाँ नहीं है। आप कुछ ऐसा कर सकते हैं:

SELECT col1, col2, col3, col4 FROM tbl

और अपने इच्छित कॉलम को मैन्युअल रूप से चुनें। हालाँकि, यदि आप बहुत सारे कॉलम चाहते हैं, तो आप बस एक करना चाहते हैं:

SELECT * FROM tbl 

और अभी अनदेखा करो जो तुम नहीं चाहते हो।

आपके विशेष मामले में, मैं सुझाव दूंगा:

SELECT * FROM tbl

जब तक आप केवल कुछ कॉलम नहीं चाहते। यदि आप केवल चार कॉलम चाहते हैं, तो:

SELECT col3, col6, col45, col 52 FROM tbl

ठीक होगा, लेकिन यदि आप 50 कॉलम चाहते हैं, तो क्वेरी बनाने वाला कोई भी कोड (बहुत?) पढ़ना मुश्किल होगा।


3
चयन करें * हमेशा एक गरीब पसंद है। इसकी सिफारिश मत करो। ऊपर पढ़ें कि यह एक एसक्यूएल एंटीपैटर्न क्यों है।
एचएलजीईएम

18

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

11

यदि आप जिस कॉलम का चयन नहीं करना चाहते थे, उसमें भारी मात्रा में डेटा था, और आप इसे स्पीड मुद्दों के कारण शामिल नहीं करना चाहते थे और आप अक्सर अन्य कॉलमों का चयन करते हैं, तो मेरा सुझाव है कि आप एक नई तालिका बनाएं एक फ़ील्ड के साथ जिसे आप आमतौर पर मूल तालिका की कुंजी के साथ नहीं चुनते हैं और फ़ील्ड को मूल तालिका से हटा देते हैं। तालिकाओं से जुड़ें जब उस अतिरिक्त क्षेत्र की वास्तव में आवश्यकता होती है।


9

आप DESCRIBE my_table का उपयोग कर सकते हैं और गतिशील रूप से SELECT स्टेटमेंट जेनरेट करने के लिए उसके परिणामों का उपयोग कर सकते हैं ।


8

मेरी मुख्य समस्या टेबल में शामिल होने के दौरान मुझे मिलने वाले कई कॉलम हैं। हालांकि यह आपके प्रश्न का उत्तर नहीं है ( एक तालिका से सभी लेकिन कुछ स्तंभों का चयन कैसे करें ), मुझे लगता है कि यह ध्यान देने योग्य है कि आप किसी विशेष तालिका से सभी कॉलमों को निर्दिष्ट करने के बजाय निर्दिष्ट कर सकते हैंtable.

यहाँ एक उदाहरण दिया गया है कि यह बहुत उपयोगी हो सकता है:

उपयोगकर्ताओं का चयन करें। *, phone.meta_value फोन के रूप में, zipcode.meta_value zipcode के रूप में

उपयोगकर्ताओं से

बाएँ फ़ोन के रूप में user_meta से जुड़ें
((users.user_id = phone.user_id) और (phone.meta_key = 'phone'))

zipcode के रूप में user_meta को छोड़ दिया जाए
((users.user_id = zipcode.user_id) और (zipcode.meta_key = 'zipcode') पर

परिणाम उपयोगकर्ता तालिका से सभी स्तंभ हैं, और दो अतिरिक्त स्तंभ जो मेटा तालिका से शामिल किए गए थे।


2
धन्यवाद, मुझे पहली तालिका के सभी स्तंभों का चयन करने की आवश्यकता है और इसमें शामिल होने में दूसरी तालिका से केवल एक क्षेत्र और आपके उत्तर ने मेरी मदद की।
मुहम्मद फलाहत

5

मुझे @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


4

स्तंभों को निर्दिष्ट करने के लिए यह अच्छा अभ्यास है कि आप सभी स्तंभों को क्वेरी करते हुए भी क्वेरी कर रहे हैं।

इसलिए मैं आपको सुझाव दूंगा कि आप प्रत्येक कॉलम का नाम स्टेटमेंट में लिखें (आपको जो नहीं चाहिए उसे छोड़कर)।

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

FROM table

यह कोड के साथ एक अनुबंध की तरह काम करता है और जब क्वेरी को देखते हैं, तो आपको पता होता है कि तालिका के स्कीमा को देखे बिना आप इसमें से कौन सा डेटा निकाल सकते हैं।
mbillard

6
@kodecraft: यह एक ही कारण के लिए अच्छा अभ्यास है कि यह एक समारोह से उसी प्रकार को वापस करने के लिए अच्छा अभ्यास है (भले ही आप उस भाषा में काम करते हैं जहां यह लागू नहीं है)। मूल रूप से सिर्फ कम आश्चर्य का सिद्धांत।
डैनियल प्राइडेन सेप

4

बस करो

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,";
   }      
}

6
जब तक आप जिस कॉलम को बाहर करना चाहते हैं वह एक विशाल बीएलओबी या कुछ और है।
बिल करविन

1
यदि आप व्यर्थ डेटा से बचने की कोशिश कर रहे हैं तो यह बुरा है।
क्रिस्टोफर इवेस

53 से 1 कॉलम को कोई फर्क नहीं पड़ना चाहिए। अगर ऐसा होता है तो यह शायद एक खराब डिजाइन है।
पेट्र पेलर

1
एसईटी * एक एसक्यूएल एंटीपैटर्न है और उत्पादन कोड में कभी भी इसका इस्तेमाल नहीं किया जाना चाहिए।
HLGEM

1
मैं इस बात से सहमत नहीं हूं कि SELECT * कुछ तरह का एंटी-पैटर्न है, जिसे प्रोडक्शन कोड में "कभी नहीं" होना चाहिए। यह बहुत स्पष्ट है कि आपने अपने सभी स्तंभों को पुनः प्राप्त कर लिया है - जैसा कि उन स्तंभों की लंबी सूची की तुलना में है, जो वास्तव में सभी क्षेत्र हो सकते हैं या नहीं। यह भी, बहुत स्पष्ट रूप से, कोड के लिए तेज है, अब तक। और कई, कई मामले हैं जहां तालिका के क्षेत्र दृश्य या रूप में बिल्कुल फ़ील्ड के अनुरूप होंगे।
ज्योफ केंडल

4

मैं सभी कॉलमों को सूचीबद्ध करने के "सरल" समाधान से सहमत हूं, लेकिन यह बोझिल हो सकता है, और टाइपोस बहुत समय बर्बाद कर सकता है। मैं एक क्वेरी में चिपकाने के लिए उपयुक्त अपने कॉलम के नाम को पुनः प्राप्त करने के लिए एक फ़ंक्शन "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



4

हां, हालांकि यह उच्च I / O हो सकता है यहां तालिका के आधार पर मैं इसके लिए मिला एक वैकल्पिक हल है।

SELECT *
INTO #temp
FROM table

ALTER TABLE #temp DROP COlUMN column_name

SELECT *
FROM #temp

यह किसी भी मामूली आकार की मेज के लिए बहुत धीमा होगा।
जोएल

3

मैं मानता हूं कि यह पर्याप्त नहीं है Select *, यदि आपको जिसकी आवश्यकता नहीं है, जैसा कि अन्यत्र उल्लेख किया गया है, एक BLOB है, आप उस ओवरहेड रेंगना नहीं चाहते हैं।

मैं आवश्यक डेटा के साथ एक दृश्यSelect * बनाऊंगा , फिर आप आराम से कर सकते हैं - अगर डेटाबेस सॉफ्टवेयर उनका समर्थन करता है। और, विशाल डेटा को किसी अन्य तालिका में डालें।


3

पहले मुझे लगा कि आप नियमित अभिव्यक्ति का उपयोग कर सकते हैं, लेकिन जैसा कि मैं MYSQL डॉक्स पढ़ रहा हूं ऐसा लगता है कि आप नहीं कर सकते। यदि मैं आप होते तो मैं एक और भाषा (जैसे PHP) का उपयोग कर सकता था कि आप जो कॉलम पाना चाहते हैं, उसे एक स्ट्रिंग के रूप में संग्रहीत करें और फिर SQL बनाने के लिए उपयोग करें।


3

मैं भी यही चाहता था इसलिए मैंने इसके बजाय एक फंक्शन बनाया।

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

तो यह कैसे काम करता है कि आप तालिका में प्रवेश करते हैं, तो एक कॉलम जिसे आप नहीं चाहते हैं या एक सरणी में: सरणी ("आईडी", "नाम", "जो कुछ भी हो)"

तो चयन में आप इसे इस तरह उपयोग कर सकते हैं:

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

या

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

3

मैं @ Mahomedalid के जवाब से सहमत हूं, लेकिन मैं एक तैयार कथन की तरह कुछ नहीं करना चाहता था और मैं सभी क्षेत्रों को टाइप नहीं करना चाहता था, इसलिए मेरे पास एक मूर्खतापूर्ण समाधान था।

Phpmyadmin-> sql-> सेलेक्ट में टेबल पर जाएं, यह क्वेरी को डंप करता है: कॉपी करें, बदलें और करें! :)


2

हालांकि मैं थॉमस के जवाब (+1;) से सहमत हूं, मैं यह कहना चाहूंगा कि मैं उस कॉलम को जोड़ना चाहूंगा जिसे आप नहीं चाहते हैं कि इसमें कोई डेटा नहीं है। यदि इसमें भारी मात्रा में पाठ, xml या बाइनरी ब्लब्स हैं, तो प्रत्येक कॉलम को व्यक्तिगत रूप से चुनने के लिए समय निकालें। अन्यथा आपके प्रदर्शन को नुकसान होगा। चीयर्स!


2

Mahomedalid द्वारा पोस्ट किए गए जवाब में एक छोटी सी समस्या है:

इनसाइड रिप्लेस फंक्शन कोड " <columns_to_delete>," द्वारा "" को रिप्लेस कर रहा था, इस रिप्लेसमेंट की समस्या है अगर रिप्लेस करने के लिए फील्ड कॉन्ट्रा स्ट्रांग में सबसे आखिरी है क्योंकि पिछले एक में कॉमा कॉमा नहीं है "," और इसे हटाया नहीं गया है डोर।

मेरा प्रस्ताब:

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" से बदल दिया जाता है मेरे मामले में यह काम करता है क्योंकि मैं मेमोरी को सुरक्षित करने की कोशिश कर रहा था। (मैं जिस क्षेत्र को हटा रहा था वह लगभग 1MB का BLOB है)


2

@Mahomed अमान्य उत्तर के आधार पर, मैंने "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;

2

हो सकता है कि मेरे पास जन कोरीटैक की इंगित विसंगति का हल है

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'

1

यदि यह हमेशा एक ही कॉलम होता है, तो आप एक ऐसा दृश्य बना सकते हैं जिसमें यह नहीं है।

अन्यथा, नहीं, मुझे ऐसा नहीं लगता।


1

यदि आप चाहें तो SQL उत्पन्न करने के लिए SQL का उपयोग कर सकते हैं और इसका उत्पादन करने वाले SQL का मूल्यांकन कर सकते हैं। यह एक सामान्य समाधान है क्योंकि यह सूचना स्कीमा से स्तंभ नामों को निकालता है। यहां यूनिक्स कमांड लाइन से एक उदाहरण दिया गया है।

स्थानापन्न

  • 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निर्मित प्रश्नों में स्ट्रिंग का पुन: उपयोग कर सकते हैं ।


1

मैं इस समस्या को हल करने के लिए एक और दृष्टिकोण जोड़ना चाहूंगा, खासकर यदि आपके पास हटाने के लिए बहुत कम कॉलम हैं।

आप के लिए चयन स्टेटमेंट जेनरेट करने के लिए आप MySQL वर्कबेंच जैसे DB टूल का उपयोग कर सकते हैं , इसलिए आपको केवल जेनरेट किए गए स्टेटमेंट के लिए उन कॉलम को मैन्युअल रूप से निकालना होगा और इसे अपनी एसक्यूएल स्क्रिप्ट में कॉपी करना होगा।

MySQL कार्यक्षेत्र में इसे उत्पन्न करने का तरीका है:

तालिका पर राइट क्लिक करें -> Sql Editor को भेजें -> सभी स्टेटमेंट चुनें।


1

स्वीकृत उत्तर में कई कमियां हैं।

  • यह विफल रहता है जहां तालिका या स्तंभ नामों के लिए बैकटिक्स की आवश्यकता होती है
  • यह विफल हो जाता है यदि आप जिस कॉलम को छोड़ना चाहते हैं वह सूची में अंतिम है
  • इसमें दो बार तालिका नाम सूचीबद्ध करने की आवश्यकता होती है (एक बार चयन के लिए और दूसरा क्वेरी पाठ के लिए) जो अनावश्यक और अनावश्यक है
  • यह गलत क्रम में कॉलम नाम संभावित रूप से वापस कर सकता है

इन सभी मुद्दों को केवल 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';

0

मेरे पास एक सुझाव है लेकिन समाधान नहीं है। यदि आपके कुछ स्तंभों में बड़ा डेटा सेट है तो आपको निम्नलिखित के साथ प्रयास करना चाहिए

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

-1

Im बहुत देर से इस के लिए एक जवाब बाहर फेंक, इस तरह से मैं हमेशा से किया है और स्पष्ट रूप से, अपने 100 गुना बेहतर है और सबसे अच्छा जवाब की तुलना में neater, मैं केवल आशा करता हूँ कि कोई इसे देखेगा। और इसे उपयोगी पाते हैं

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

हो सकता है कि यह साफ-सुथरा हो, लेकिन यह इस सवाल का जवाब नहीं देता: उसने php के बारे में नहीं पूछा है, और आप जो चाहते हैं उसका चयन नहीं करते हैं या परिणाम देते हैं, लेकिन केवल php सरणी में वह कॉलम होता है जो वह चाहता है।
gou1

2
-1। यह SQL कोड नहीं है, और SELECTयहाँ कोई कथन नहीं है - शब्द एक बार भी नहीं होता है।
फ्रूंगी

यह केवल उस सीमा तक ही सही है कि (a) आप SQL की तुलना में PHP के साथ अधिक सहज हैं, या (b) आपको पठनीयता के लिए कई लाइनों पर अपना कोड फैलाना पसंद है। मैं बिंदु (बी) स्वीकार करेंगे। आपका दृष्टिकोण भी कम प्रदर्शन वाला होगा, हालांकि कई उपयोग मामलों में अंतर मामूली होगा। अपने प्रश्न पर अन्य टिप्पणियाँ भी देखें। के बारे में चिल्लाने के लायक नहीं है, इसलिए सुझाव दें कि आप अपनी अनुचित टिप्पणी को मूल प्रश्न से हटा दें।
mc0e

-5

सेलेक्ट * एक SQL एंटीपैटर्न है। इसे कई कारणों से उत्पादन कोड में उपयोग नहीं किया जाना चाहिए:

इसे प्रोसेस करने में थोड़ा अधिक समय लगता है। जब चीजें लाखों बार चलाई जाती हैं, तो वे छोटे टुकड़े मायने रख सकते हैं। एक धीमा डेटाबेस जहां धीमापन इस प्रकार की मैला कोडिंग के कारण होता है, प्रदर्शन ट्यून के लिए सबसे कठिन प्रकार है।

इसका मतलब है कि आप शायद ज़रूरत से ज़्यादा डेटा भेज रहे हैं, जो सर्वर और नेटवर्क की अड़चनों का कारण बनता है। यदि आपके पास एक आंतरिक जुड़ाव है, तो आपकी आवश्यकता से अधिक डेटा भेजने की संभावना 100% है।

यह रखरखाव की समस्याओं का कारण बनता है, खासकर जब आपने नए कॉलम जोड़े हैं जिन्हें आप हर जगह नहीं देखना चाहते हैं। इसके अलावा यदि आपके पास एक नया कॉलम है, तो आपको उस कॉलम के साथ क्या करना है, यह निर्धारित करने के लिए इंटरफ़ेस में कुछ करने की आवश्यकता हो सकती है।

यह विचारों को तोड़ सकता है (मुझे पता है कि यह एसक्यूएल सर्वर में सच है, यह mysql में सच हो सकता है या नहीं भी हो सकता है)।

यदि कोई व्यक्ति एक अलग क्रम में स्तंभों के साथ तालिकाओं के पुनर्निर्माण के लिए मूर्खतापूर्ण है (जो आपको नहीं करना चाहिए, लेकिन यह सभी समय होता है), सभी प्रकार के कोड टूट सकते हैं। उदाहरण के लिए एक इंसर्ट कोड के लिए कोड जहाँ आप शहर को एड्रेस_3 फ़ील्ड में डाल रहे हैं, बिना बताए डीबास करें, डेटाबेस केवल कॉलम के आदेश पर जा सकता है। यह काफी बुरा है जब डेटा प्रकार बदलते हैं लेकिन बदतर तब होता है जब स्वैप किए गए कॉलम में एक ही डेटाटाइप होता है क्योंकि आप कुछ समय के लिए खराब डेटा डालने के लिए जा सकते हैं जो कि सफाई के लिए एक गड़बड़ है। आपको डेटा अखंडता के बारे में देखभाल करने की आवश्यकता है।

यदि इसे एक इंसर्ट में इस्तेमाल किया जाता है, तो यह इंसर्ट को तोड़ देगा यदि एक नया कॉलम एक टेबल में जोड़ा जाता है लेकिन दूसरे में नहीं।

यह ट्रिगर तोड़ सकता है। ट्रिगर समस्याओं का निदान करना मुश्किल हो सकता है।

कॉलम नामों में जोड़ने के लिए लगने वाले समय के खिलाफ यह सब जोड़ें (बिल्ली आपके पास एक इंटरफ़ेस भी हो सकता है जो आपको कॉलम नामों पर खींचने की अनुमति देता है (मुझे पता है कि मैं एसक्यूएल सर्वर में करता हूं, मैं शर्त लगा सकता हूं कि कोई रास्ता है यह कुछ उपकरण है जो आप 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 & कीवर्ड = एसक्यूएल + antipatterns

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.