एक पंक्ति की प्रतिलिपि कैसे करें और MySQL में एक ऑटोइनक्रीमेंट फ़ील्ड के साथ एक ही तालिका में डालें?


233

MySQL में मैं एक पंक्ति को ऑटोइन्क्रिमेंट के साथ कॉपी करने की कोशिश कर रहा हूं column ID=1और डेटा को एक नई पंक्ति के साथ एक ही तालिका में सम्मिलित कर रहा हूं column ID=2

मैं इसे एक ही क्वेरी में कैसे कर सकता हूं?

जवाबों:


351

उपयोग करें INSERT ... SELECT:

insert into your_table (c1, c2, ...)
select c1, c2, ...
from your_table
where id = 1

जहां c1, c2, ...को छोड़कर सभी स्तंभ हैं id। यदि आप स्पष्ट रूप idसे 2 के साथ सम्मिलित करना चाहते हैं, तो उसे अपनी INSERT कॉलम सूची और अपने चयन में शामिल करें:

insert into your_table (id, c1, c2, ...)
select 2, c1, c2, ...
from your_table
where id = 1

आपको idपाठ्यक्रम के दूसरे मामले में 2 के संभावित डुप्लिकेट का ध्यान रखना होगा ।


1
आप प्रोग्राम को तब INFORMATION_SCHEMA का उपयोग करके स्तंभों के नाम प्राप्त कर सकते हैं ... मुझे आश्चर्य है कि क्या आप इसे उप-क्वेरी और कुछ स्ट्रिंग फ़ंक्शन के रूप में कर सकते हैं?
हम्मम

1
@Yzmir: आप गतिशील एसक्यूएल का उपयोग करने के लिए समाप्त हो जाएगा और आमतौर पर एक संग्रहीत प्रक्रिया के निर्माण की आवश्यकता होगी। लगता है जब आप स्तंभ नाम की एक सूची वैसे भी होना चाहिए की तुलना में अधिक परेशानी की तरह लगता है।
म्यू

6
सहमत ... मेरे अनुभव से एक बार जब आप संग्रहीत प्रक्रिया पर जाते हैं तो आप वापस नहीं जाते हैं - अब आप उस डेटाबेस से शादी कर चुके हैं और जब भी आप बदलना चाहते हैं तो लागतों में जुड़ जाता है।
यज़्मीर रामिरेज़

11
@YzmirRamirez, आप इसे ध्वनि की तरह बनाते हैं जैसे शादी स्वाभाविक रूप से एक बुरी चीज है। :)
प्रो। फॉकन

1
अन्य सभी कॉपी किए गए फ़ील्ड के साथ कॉलम में एक कस्टम मान कैसे जोड़ें?
मनीष कुमार

49

IMO, सबसे अच्छा लगता है कि sql स्टेटमेंट का उपयोग केवल उस पंक्ति को कॉपी करने के लिए किया जाता है, जबकि एक ही समय में केवल उन कॉलम को संदर्भित करना चाहिए जो आप बदलना चाहते हैं और बदलना चाहते हैं।

CREATE TEMPORARY TABLE temp_table ENGINE=MEMORY

SELECT * FROM your_table WHERE id=1;
UPDATE temp_table SET id=NULL; /* Update other values at will. */

INSERT INTO your_table SELECT * FROM temp_table;
DROP TABLE temp_table;

यह भी देखें av8n.com - कैसे एक एसक्यूएल रिकॉर्ड क्लोन करें

लाभ:

  • SQL कथन 2 में केवल उन फ़ील्ड्स का उल्लेख है जिन्हें क्लोनिंग प्रक्रिया के दौरान बदलने की आवश्यकता है। वे अन्य क्षेत्रों के बारे में - या देखभाल के बारे में नहीं जानते हैं। अन्य क्षेत्र बस सवारी के लिए अपरिवर्तित हैं। यह एसक्यूएल स्टेटमेंट को लिखने में आसान, पढ़ने में आसान, बनाए रखने में आसान और अधिक एक्स्टेंसिबल बनाता है।
  • केवल साधारण MySQL स्टेटमेंट्स का उपयोग किया जाता है। कोई अन्य उपकरण या प्रोग्रामिंग भाषाओं की आवश्यकता नहीं है।
  • एक your_tableपरमाणु ऑपरेशन में एक पूरी तरह से सही रिकॉर्ड डाला जाता है ।

3
यह सीम, कि यह अच्छी चाल (मुझे यह पसंद है, लेकिन यह मेरे लिए काम नहीं करता है) उन टेबलों पर काम नहीं करता है जिनमें TEXT / VARCHAR कॉलम हैं। मैंने इसे आज़माया और मिला: (1163): प्रयुक्त टेबल प्रकार BLOB / TEXT कॉलम का समर्थन नहीं करता है। यह निश्चित रूप से MySQL पर उपयोग को बहुत सीमित करता है! हो सकता है, कि भविष्य में इन सीमाओं को हटा दिया जाए या अन्य डीबी-सिस्टम पर यह काम करता है, लेकिन अभी के लिए यह वास्तव में सीमित है।
Juergen

मुझे वास्तव में अस्थायी तालिका का चतुर उपयोग पसंद है। एक टन कॉलम वाली तालिकाओं के लिए इतना उपयोगी!
प्लाज्मा

1
अच्छा लग रहा है, लेकिन जब मैं MySQL में पहली क्वेरी चलाता हूं, तो मुझे मिलता है Error Code: 1113. A table must have at least 1 column
physicalattraction

3
बहुत सारे कॉलम के लिए सर्वश्रेष्ठ उत्तर। लेकिन SET id=NULLत्रुटि हो सकती है Column 'id' cannot be null। द्वारा प्रतिस्थापित किया जाना चाहिएUPDATE temp_table SET id = (SELECT MAX(id) + 1 as id FROM your_table);
मोडर

1
@physicalattraction आपको यह सुनिश्चित करने की आवश्यकता है कि पहली दो पंक्तियाँ एक कथन हैं।
समुराई

16

कहो मेज है user(id, user_name, user_email)

आप इस क्वेरी का उपयोग कर सकते हैं:

INSERT INTO user (SELECT NULL,user_name, user_email FROM user WHERE id = 1)

29
INSERT का उपयोग करते समय आपको हमेशा कॉलम के नाम निर्दिष्ट करने चाहिए , अन्यथा आपके स्कीमा बदलने पर आपको अजीब और दिलचस्प कीड़े मिलेंगे।
म्यू

2
अजीब और दिलचस्प, वास्तव में। : D
स्पार्कशीट्स

Sqlite के साथ काम नहीं करता है। Result: near "SELECT": syntax error
kyb

10

इससे मदद मिली और यह एक BLOB / TEXT कॉलम का समर्थन करता है।

CREATE TEMPORARY TABLE temp_table
AS
SELECT * FROM source_table WHERE id=2;
UPDATE temp_table SET id=NULL WHERE id=2;
INSERT INTO source_table SELECT * FROM temp_table;
DROP TEMPORARY TABLE temp_table;
USE source_table;

किस तरह से यह यहां अन्य उत्तरों से बेहतर है?
स्मार

3
मुझे लगता है कि यह बहुत अच्छा है अगर आपके पास 100 क्षेत्रों के साथ एक तालिका है। सिवाय इसके कि आईडी पर एक अशक्त बाधा नहीं हो सकती है जो इसे विफल बनाती है
Lo bec Faure-Lacroix

त्रुटि कोड: 1136. कॉलम संख्या पंक्ति 1 पर मान गणना से मेल नहीं खाती
ओलेक्सी किस्लीत्सिन

यह बहुत अच्छा है यदि आपके पास 100 कॉलम के साथ एक तालिका है।
टायलर एस। लोपर

क्या यह परवस ने वर्षों पहले नहीं कहा था?
टूलमेकरसेव

7

एक त्वरित, स्वच्छ समाधान के लिए जिसे आपको कॉलम का नाम देने की आवश्यकता नहीं है, आप यहां बताए अनुसार तैयार किए गए विवरण का उपयोग कर सकते हैं: https://stackoverflow.com/a/23964285/292677

यदि आपको एक जटिल समाधान की आवश्यकता है तो आप अक्सर ऐसा कर सकते हैं, आप इस प्रक्रिया का उपयोग कर सकते हैं:

DELIMITER $$

CREATE PROCEDURE `duplicateRows`(_schemaName text, _tableName text, _whereClause text, _omitColumns text)
SQL SECURITY INVOKER
BEGIN
  SELECT IF(TRIM(_omitColumns) <> '', CONCAT('id', ',', TRIM(_omitColumns)), 'id') INTO @omitColumns;

  SELECT GROUP_CONCAT(COLUMN_NAME) FROM information_schema.columns 
  WHERE table_schema = _schemaName AND table_name = _tableName AND FIND_IN_SET(COLUMN_NAME,@omitColumns) = 0 ORDER BY ORDINAL_POSITION INTO @columns;

  SET @sql = CONCAT('INSERT INTO ', _tableName, '(', @columns, ')',
  'SELECT ', @columns, 
  ' FROM ', _schemaName, '.', _tableName, ' ',  _whereClause);

  PREPARE stmt1 FROM @sql;
  EXECUTE stmt1;
END

आप इसे चला सकते हैं:

CALL duplicateRows('database', 'table', 'WHERE condition = optional', 'omit_columns_optional');

उदाहरण

duplicateRows('acl', 'users', 'WHERE id = 200'); -- will duplicate the row for the user with id 200
duplicateRows('acl', 'users', 'WHERE id = 200', 'created_ts'); -- same as above but will not copy the created_ts column value    
duplicateRows('acl', 'users', 'WHERE id = 200', 'created_ts,updated_ts'); -- same as above but also omits the updated_ts column
duplicateRows('acl', 'users'); -- will duplicate all records in the table

अस्वीकरण: यह समाधान केवल उन लोगों के लिए है जो अक्सर कई तालिकाओं में पंक्तियों को दोहरा रहे हैं, अक्सर। यह एक दुष्ट उपयोगकर्ता के हाथों में खतरनाक हो सकता है।


3

आप '0' में ऑटो-इंक्रीमेंट के लिए कॉलम के मान के रूप में भी पास कर सकते हैं, रिकॉर्ड बनाते समय सही मूल्य का उपयोग किया जाएगा। यह अस्थायी तालिकाओं की तुलना में बहुत आसान है।

स्रोत: MySQL में पंक्तियों की प्रतिलिपि बनाना (दूसरा कमेंट, TRiG द्वारा, पहले समाधान के लिए, विद्या द्वारा देखें)


1
यह विधि नए MySQL संस्करणों के साथ काम करती है जब NULL स्वीकार्य नहीं है।
अरे

3

यहाँ बहुत सारे शानदार उत्तर। नीचे संग्रहीत कार्यविधि का एक नमूना है जो मैंने वेब ऐप के लिए इस कार्य को पूरा करने के लिए लिखा था जिसे मैं विकसित कर रहा हूं:

-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON

-- Create Temporary Table
SELECT * INTO #tempTable FROM <YourTable> WHERE Id = Id

--To trigger the auto increment
UPDATE #tempTable SET Id = NULL 

--Update new data row in #tempTable here!

--Insert duplicate row with modified data back into your table
INSERT INTO <YourTable> SELECT * FROM #tempTable

-- Drop Temporary Table
DROP TABLE #tempTable

MariaDB / MySQL सेटिंग आईडी के मौजूदा संस्करण में = null # 1048 देता है - कॉलम 'id' शून्य नहीं हो सकता है, जिससे id = 0 कार्य की स्थापना होती है;
आश्रयदीपेरे

2
insert into MyTable(field1, field2, id_backup)
    select field1, field2, uniqueId from MyTable where uniqueId = @Id;

3
यहाँ अन्य उत्तरों की तुलना में यह कैसे बेहतर है?
स्मार

1
@ सिमर इमो यह समझने के लिए क्लीनर है
सतबीर कीरा

2

यदि आप MySQL कार्यक्षेत्र का उपयोग करने में सक्षम हैं, तो आप पंक्ति को राइट-क्लिक करके और 'कॉपी पंक्ति' का चयन करके ऐसा कर सकते हैं, और फिर खाली पंक्ति पर राइट-क्लिक करके 'पेस्ट पंक्ति' का चयन कर सकते हैं, और फिर आईडी बदल सकते हैं, और फिर 'लागू करें' पर क्लिक करें।

पंक्ति की प्रतिलिपि बनाएँ:

यहां छवि विवरण दर्ज करें

प्रतिलिपि बनाई गई पंक्ति को रिक्त पंक्ति में चिपकाएँ:

यहां छवि विवरण दर्ज करें

आईडी बदलें:

यहां छवि विवरण दर्ज करें

लागू:

यहां छवि विवरण दर्ज करें


0

मैं उसी सुविधा की तलाश में था लेकिन मैं MySQL का उपयोग नहीं करता। मैं प्राथमिक कुंजी (आईडी) को छोड़कर सभी क्षेत्रों को कॉपी करना चाहता था। यह एक शॉट क्वेरी थी, जिसे किसी स्क्रिप्ट या कोड में उपयोग नहीं किया जाना था।

मुझे पीएल / एसक्यूएल के साथ अपना रास्ता मिल गया लेकिन मुझे यकीन है कि कोई अन्य एसक्यूएल आईडीई करेगा। मैंने एक बेसिक किया

SELECT * 
FROM mytable 
WHERE id=42;

फिर इसे एक SQL फ़ाइल में निर्यात करें जहाँ मुझे मिल सके

INSERT INTO table (col1, col2, col3, ... , col42) 
VALUES (1, 2, 3, ..., 42);

मैंने अभी इसे संपादित किया और इसका उपयोग किया:

INSERT INTO table (col1, col2, col3, ... , col42) 
VALUES (mysequence.nextval, 2, 3, ..., 42);

0

मैं इस बात की भिन्नता का उपयोग करता हूं कि बहुत कम पोस्ट किया गया है:

INSERT INTO something_log
SELECT NULL, s.*
FROM something AS s
WHERE s.id = 1;

जब तक तालिकाओं में समान फ़ील्ड होते हैं (लॉग टेबल पर ऑटो वेतन वृद्धि को छोड़कर), तब यह अच्छी तरह से काम करता है।

चूंकि मैं जब भी संभव हो संग्रहीत प्रक्रियाओं का उपयोग करता हूं (अन्य प्रोग्रामर जो डेटाबेस से बहुत परिचित नहीं हैं, पर जीवन को आसान बनाने के लिए), यह एक मेज पर एक नया क्षेत्र जोड़ने पर हर बार वापस जाने और प्रक्रियाओं को अपडेट करने की समस्या को हल करता है।

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

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

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


0
INSERT INTO `dbMyDataBase`.`tblMyTable` 
(
    `IdAutoincrement`, 
    `Column2`, 
    `Column3`, 
    `Column4` 
) 

चुनते हैं 
    शून्य,  
    `Column2`, 
    `Column3`, 
    'CustomValue' AS Column4 
`DbMyDataBase`.`tblMyTable` से 
जहां `tblMyTable`.`Cumn 2` = 'UniqueValueOfTheKey' 
; 
/ * mySQL 5.6 * /

3
कुछ और विस्तृत विवरण जोड़ने की कोशिश करें, या यह अन्य उत्तरों पर कैसे फैलता है
अज़गी

-1

उस पंक्ति को डंप करें जिसे आप sql करना चाहते हैं और फिर जनरेट किए गए SQL का उपयोग करें, इसे वापस आयात करने के लिए ID कॉलम को कम करें।

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