2011-11-28 8 views
15

कैसे आप डालने का चयन किया है पंक्तियों सभी स्तंभों का ब्यौरा बिना चयन करें:INSERT INTO ... MySQL में एसक्यूएल का उपयोग कर जहां <code>table_target</code> को <code>table_source</code> से

  • दोनों तालिकाओं में एक ही स्कीमा
  • सभी स्तंभों के अलावा स्थानांतरित करना चाहिए है ऑटो वेतन वृद्धि id
  • स्पष्ट रूप से सभी कॉलम नामों में लेखन, कि के रूप में कठिन

तुच्छ होगा बिना INSERT INTO table_target SELECT * FROM table_source प्राथमिक कुंजी के लिए डुप्लिकेट प्रविष्टियों पर विफल रहता है।

उत्तर

11

में मदद करता है या तो आप क्षेत्रों आप डालने में चाहते हैं ... चयन के सभी सूची, या आप का उपयोग आपके लिए सूची बनाने के लिए बाहरी रूप से कुछ और।

एसक्यूएल में SELECT * except somefield FROM जैसा कुछ नहीं है, इसलिए आपको बुलेट काटने और फील्ड नाम लिखना होगा।

INSERT INTO table_target SELECT NULL, column_name1, column_name2, column_name3, ... 
    FROM table_source; 

बस ऑटो वेतन वृद्धि आईडी क्षेत्र के लिए एक मूल्य के रूप में शून्य से पारित -

+2

आप ठीक है, अंत में मैंने स्पष्ट वाक्यविन्यास का उपयोग किया। पूर्णता के लिए: आसानी से कॉलम सूची ['DESCRIBE'] (http://dev.mysql.com/doc/refman/5.0/en/describe.html) का उपयोग करके प्राप्त करें और फिर सिंटैक्स 'INSERT INTO तालिका 1 (फ़ील्ड 1, फ़ील्ड 2) का उपयोग करें , फ़ील्ड 3) तालिका 2। फ़ील्ड 1, table2.field2, table2.field3 तालिका 2 से; ' – Jonathan

+0

सीएसवी फ़ील्ड नाम प्राप्त करने का सबसे आसान तरीका: 'चुनें CONCAT (GROUP_CONCAT (COLUMN_NAME SEPARATOR', ')," \ n ") INFORMATION_SCHEMA से COLUMNS जहां TABLE_SCHEMA = 'dbname' और TABLE_NAME = 'tablename' समूह TABLE_NAME' – Hafenkranich

2

बेशक, प्राथमिक कुंजी अद्वितीय होना चाहिए। यह इस बात पर निर्भर करता है कि आप क्या हासिल करना चाहते हैं, लेकिन आप पंक्तियों को प्राथमिक कुंजी के साथ बाहर कर सकते हैं जो पहले से मौजूद है।

INSERT INTO table_target SELECT * FROM table_source 
WHERE table_source.id NOT IN (SELECT id FROM table_target) 

अद्यतन: जब से तुम भी अतिरिक्त पंक्तियों की जरूरत है, तो आप पहले के विवाद को दूर करना चाहिए, table_source रिश्ते हैं करता है? आप उन कुंजियों को नहीं बदल सकता है, तो:

UPDATE table_source SET id = id + 1000 
WHERE id IN (SELECT id FROM table_target) 

कहाँ 1000, एक स्थिर, काफी बड़ा है ताकि वे अपनी मेज के अंत के बाद जाना है।

+0

मैं उन पंक्तियों की जरूरत भी ... – Jonathan

+0

ठीक है, इस सवाल का जवाब – stivlo

+0

एक अच्छी युक्ति है कि केवल यदि आप 'table_source' की ओर इशारा करते विदेशी कुंजी नहीं है अपडेट किया गया। साथ ही, अगर निरंतर उपयोग करने के बजाय 'table_target' में सबसे बड़ी आईडी को गतिशील रूप से लाने का कोई तरीका हो सकता है, तो यह थोड़ा बेहतर कामकाज होगा – Jonathan

1

मैं आप की तरह वाक्यविन्यास इस्तेमाल कर सकते हैं लगता है:

 
INSERT INTO table (a,b,c) VALUES (1,2,3) 
    ON DUPLICATE KEY UPDATE c=c+1; 

REF: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html आशा है कि यह

+0

जो अब उन मूल रिकॉर्डों को तोड़ता है जो मूल रिकॉर्ड थे ... –

15

कॉलम नाम निर्दिष्ट किया जाना है।

+0

धन्यवाद! इससे मदद मिली। – Hafenkranich

0

INSERT IGNORE डुप्लिकेट पंक्तियों को बस "बाईपास" करें।

http://dev.mysql.com/doc/refman/5.5/en/insert.html

+0

वह नहीं होगा ... भयानक ?! – Jonathan

+0

नहीं, अगर अनदेखी पंक्तियां आपको आवश्यक पंक्तियां हैं। अन्यथा, आप आईडी (या अन्य अद्वितीय फ़ील्ड) और 'INSERT' द्वारा हटा सकते हैं। –

3

थकाऊ लेकिन सुरक्षित और सही।

स्तंभों की सूची प्रदान किए बिना INSERT बयान लिखना कोड को ले जाता है जो डीबग करना कठिन होता है और, सबसे महत्वपूर्ण बात यह है कि तालिका की परिभाषा बदल जाती है तो बहुत ही कमजोर कोड टूट जाएगा।

यदि आप पूरी तरह से कॉलम नाम लिख नहीं सकते हैं तो आपके कोड में एक टूल बनाने के लिए अपेक्षाकृत आसान है जो आपके लिए अल्पविराम से अलग सूची तैयार करेगा।

0

आप शायद इसे तैयार वक्तव्य के साथ कर सकते हैं।

PREPARE table_target_insert FROM 'INSERT INTO table_target SELECT ? FROM table_source'; 
SET @cols:=''; 
SELECT @cols:=GROUP_CONCAT(IF(column_name = 'id','NULL',column_name) separator ",") FROM information_schema.columns WHERE table_name='table_source'; 
EXECUTE table_target_insert USING @cols; 
0

ऐसा लगता है जैसे कॉलम को एक MySQL तैयार वक्तव्य में प्लेसहोल्डर के रूप में नहीं दिया जा सकता है। मैं परीक्षण के लिए निम्नलिखित समाधान तैयार की है:

SET @schema_db = 'DB'; 
SET @table = 'table'; 
SET @cols = (SELECT CONCAT(GROUP_CONCAT(COLUMN_NAME SEPARATOR ', '), "\n") FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @schema_db AND TABLE_NAME = @table GROUP BY TABLE_NAME); 
SET @Querystr = CONCAT('SELECT',' ', @cols,' ','FROM',' ',@schema_db,'.',@table,' ', 'Limit 5'); 
PREPARE stmt FROM @Querystr; 
EXECUTE stmt; 
1

यह वह जगह है 'डालने की जगह' आदेश से बड़े पैमाने पर अद्यतन करने के लिए अपने अंतिम समाधान।

SET @@session.group_concat_max_len = @@global.max_allowed_packet; 
SET @schema_db = 'db'; 
SET @tabl = 'table'; 
SET @cols = (SELECT CONCAT('`',GROUP_CONCAT(COLUMN_NAME SEPARATOR '`, `'), '`') FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @schema_db AND TABLE_NAME = @tabl GROUP BY TABLE_NAME); 
SET @Querystr = CONCAT('REPLACE INTO ',@schema_db,'.',@tabl,' SELECT ', @cols,' FROM import.tbl_', @tabl); 

PREPARE stmt FROM @Querystr; 
EXECUTE stmt; 
संबंधित मुद्दे