मैं एक को छोड़कर एक निश्चित MySQL तालिका से सभी कॉलम प्राप्त करने के लिए एक चयन कथन का उपयोग करने की कोशिश कर रहा हूं। क्या ऐसा करने के लिए एक सरल तरीका है?
संपादित करें: इस तालिका में 53 स्तंभ हैं (मेरा विवरण नहीं)
मैं एक को छोड़कर एक निश्चित 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 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') पर
परिणाम उपयोगकर्ता तालिका से सभी स्तंभ हैं, और दो अतिरिक्त स्तंभ जो मेटा तालिका से शामिल किए गए थे।
मुझे @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 *
, यदि आपको जिसकी आवश्यकता नहीं है, जैसा कि अन्यत्र उल्लेख किया गया है, एक BLOB है, आप उस ओवरहेड रेंगना नहीं चाहते हैं।
मैं आवश्यक डेटा के साथ एक दृश्य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)."`";
}
}
तो यह कैसे काम करता है कि आप तालिका में प्रवेश करते हैं, तो एक कॉलम जिसे आप नहीं चाहते हैं या एक सरणी में: सरणी ("आईडी", "नाम", "जो कुछ भी हो)"
तो चयन में आप इसे इस तरह उपयोग कर सकते हैं:
mysql_query("SELECT ".$db->getColsExcept('table',array('id','bigtextcolumn'))." FROM table");
या
mysql_query("SELECT ".$db->getColsExcept('table','bigtextcolumn')." FROM table");
हालांकि मैं थॉमस के जवाब (+1;) से सहमत हूं, मैं यह कहना चाहूंगा कि मैं उस कॉलम को जोड़ना चाहूंगा जिसे आप नहीं चाहते हैं कि इसमें कोई डेटा नहीं है। यदि इसमें भारी मात्रा में पाठ, xml या बाइनरी ब्लब्स हैं, तो प्रत्येक कॉलम को व्यक्तिगत रूप से चुनने के लिए समय निकालें। अन्यथा आपके प्रदर्शन को नुकसान होगा। चीयर्स!
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 है)
@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;
हो सकता है कि मेरे पास जन कोरीटैक की इंगित विसंगति का हल है
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 का उपयोग कर सकते हैं और इसका उत्पादन करने वाले SQL का मूल्यांकन कर सकते हैं। यह एक सामान्य समाधान है क्योंकि यह सूचना स्कीमा से स्तंभ नामों को निकालता है। यहां यूनिक्स कमांड लाइन से एक उदाहरण दिया गया है।
स्थानापन्न
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 वर्कबेंच जैसे DB टूल का उपयोग कर सकते हैं , इसलिए आपको केवल जेनरेट किए गए स्टेटमेंट के लिए उन कॉलम को मैन्युअल रूप से निकालना होगा और इसे अपनी एसक्यूएल स्क्रिप्ट में कॉपी करना होगा।
MySQL कार्यक्षेत्र में इसे उत्पन्न करने का तरीका है:
तालिका पर राइट क्लिक करें -> Sql Editor को भेजें -> सभी स्टेटमेंट चुनें।
स्वीकृत उत्तर में कई कमियां हैं।
इन सभी मुद्दों को केवल 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';
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]);
SELECT
यहाँ कोई कथन नहीं है - शब्द एक बार भी नहीं होता है।
सेलेक्ट * एक 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