MYSQL: Làm thế nào để sao chép toàn bộ một hàng từ bảng này sang bảng khác trong mysql với bảng thứ hai có thêm một cột?


76

Tôi có hai bảng có cấu trúc giống hệt nhau ngoại trừ một cột ... Bảng 2 có cột bổ sung mà tôi sẽ chèn CURRENT_DATE ()

Tôi muốn sao chép tất cả các giá trị từ table1 sang table2.

nếu tôi sử dụng

INSERT INTO dues_storage SELECT * FROM dues WHERE id=5;

nó ném ra một lỗi chỉ ra sự khác biệt về số lượng cột.

Tôi có hai câu hỏi về điều đó:

  1. Làm cách nào để giải quyết vấn đề này?
  2. và làm cách nào để thêm giá trị cho cột ngày bổ sung (CURRENT_DATE ()) trong table2 trong cùng một câu lệnh này?

Bạn có thể nhìn vào cái này. Nó đã làm việc cho tôi trong mysql. stackoverflow.com/questions/57168/…
Shreyo

Câu trả lời:


96

Để tinh chỉnh câu trả lời từ Zed và trả lời bình luận của bạn:

INSERT INTO dues_storage
SELECT d.*, CURRENT_DATE()
FROM dues d
WHERE id = 5;

Xem bình luận của TJ Crowder


51
Hãy RẤT KỸ khi làm điều này. Nó hoạt động, nhưng nó giả định thứ tự của các cột trong hai bảng là giống hệt nhau; nó không khớp theo tên cột và cố ép các giá trị để khớp, điều này có thể gây ra kết quả không mong muốn. Bây giờ, nếu cấu trúc phát triển của bạn đảm bảo các thứ tự cột giống với cột cuối cùng, thì đó là một cách thuận tiện và đơn giản để làm điều đó, nhưng lưu ý là quan trọng.
TJ Crowder

May mắn thay, thứ tự là như nhau. Tôi sẽ ghi nhớ để giữ cho cấu trúc giống hệt nhau ngay cả trong tương lai. cảm ơn tất cả!
dùng165242

@crunchdog nên tổ chức truy vấn như thế nào nếu tôi cần đặt wherenhư thế A.id = B.idnào?
Eugene

2
Bạn có cần CURRENT_DATE () không? Bạn có thể đặt loại trường đó thành TimeStamp và đặt mặc định thành CURRENT_TIMESTAMP. Nó sẽ điền DateTime hiện tại vào thời điểm tạo bản ghi.
Chiwda

53

Cách an toàn nhất để làm điều đó là chỉ định đầy đủ các cột cả để chèn và trích xuất. Không có gì đảm bảo (đối với ứng dụng) rằng một trong hai thứ này sẽ là thứ tự mà bạn nghĩ.

insert into dues_storage (f1, f2, f3, cd)
    select f1, f2, f3, current_date() from dues where id = 5;

Nếu bạn lo lắng về việc phải thay đổi nhiều trang PHP thực hiện điều này (như bạn dường như chỉ ra trong nhận xét cho một câu trả lời khác), điều này đã chín muồi cho một thủ tục được lưu trữ. Bằng cách đó, tất cả các trang PHP của bạn chỉ cần gọi thủ tục được lưu trữ với (ví dụ) chỉ là ID để sao chép và nó kiểm soát quá trình sao chép thực tế. Bằng cách đó, chỉ có một nơi mà bạn cần duy trì mã, và theo ý kiến ​​của tôi, DBMS là nơi thích hợp để làm điều đó.


vâng .. nhưng tôi chỉ mới bắt đầu. Bây giờ tôi phải tìm hiểu những thủ tục được lưu trữ là gì, cảm ơn! một điều nữa để học ngày hôm nay!
dùng165242

1
đây là câu trả lời hay nhất
Mike Volmar

8
INSERT INTO dues_storage
SELECT field1, field2, ..., fieldN, CURRENT_DATE()
FROM dues
WHERE id = 5;

có rất nhiều trường trong bảng, có cách nào ngắn hơn không? Nếu tôi thay đổi cấu trúc bảng ở đó, tôi cũng phải nhớ thay đổi các trang php.
dùng165242

bạn có thể thoát khỏi nó với lệ phí. *
Zed

4

Hy vọng điều này sẽ giúp ai đó ... Đây là một đoạn mã PHP nhỏ mà tôi đã viết trong trường hợp bạn cần sao chép một số cột nhưng không phải những cột khác và / hoặc các cột không theo cùng một thứ tự trên cả hai bảng. Miễn là các cột được đặt tên giống nhau, điều này sẽ hoạt động. Vì vậy, nếu bảng A có [userid, handle, something] và tableB có [userID, handle, timestamp], thì bạn "CHỌN userID, handle, NOW () làm dấu thời gian TỪ tableA", sau đó nhận kết quả của điều đó và truyền kết quả làm tham số đầu tiên cho hàm này ($ z). $ toTable là tên chuỗi cho bảng bạn đang sao chép và $ link_identifier là db bạn đang sao chép vào. Điều này tương đối nhanh đối với các tập dữ liệu nhỏ. Bạn không nên cố gắng di chuyển hơn vài nghìn hàng cùng một lúc theo cách này trong cài đặt sản xuất.

 function mysql_multirow_copy($z,$toTable,$link_identifier) {
            $fields = "";
            for ($i=0;$i<mysql_num_fields($z);$i++) {
                if ($i>0) {
                    $fields .= ",";
                }
                $fields .= mysql_field_name($z,$i);
            }
            $q = "INSERT INTO $toTable ($fields) VALUES";
            $c = 0;
            mysql_data_seek($z,0); //critical reset in case $z has been parsed beforehand. !
            while ($a = mysql_fetch_assoc($z)) {
                foreach ($a as $key=>$as) {
                    $a[$key] = addslashes($as);
                    next ($a);
                }
                if ($c>0) {
                    $q .= ",";
                }
                $q .= "('".implode(array_values($a),"','")."')";
                $c++;
            }
            $q .= ";";
            $z = mysql_query($q,$link_identifier);
            return ($q);
        }

0

Ngoài ra, bạn có thể sử dụng Truy vấn bên trong để làm như vậy.

SQL> INSERT INTO <NEW_TABLE> SELECT * FROM CUSTOMERS WHERE ID IN (SELECT ID FROM <OLD_TABLE>);

Hi vọng điêu nay co ich!


0
SET @sql = 
CONCAT( 'INSERT INTO <table_name> (', 
    (
        SELECT GROUP_CONCAT( CONCAT('`',COLUMN_NAME,'`') ) 
            FROM information_schema.columns 
            WHERE table_schema = <database_name>
                AND table_name = <table_name>
                AND column_name NOT IN ('id')
    ), ') SELECT ', 
    ( 
        SELECT GROUP_CONCAT(CONCAT('`',COLUMN_NAME,'`')) 
        FROM information_schema.columns 
        WHERE table_schema = <database_name>
            AND table_name = <table_source_name>
            AND column_name NOT IN ('id')  
    ),' from <table_source_name> WHERE <testcolumn> = <testvalue>' );  

PREPARE stmt1 FROM @sql; 
execute stmt1;

Tất nhiên, hãy thay thế các giá trị <> bằng các giá trị thực và xem các trích dẫn của bạn.


-3

Tôi chỉ muốn thêm đoạn mã nhỏ này mà nó hoạt động tốt cho tôi.

INSERT INTO your_target_table SELECT * FROM your_rescource_table WHERE id = 18;

Và trong khi tôi đang ở đó, hãy gửi lời cảm ơn lớn đến Sequel Pro, nếu bạn không sử dụng nó, tôi thực sự khuyên bạn nên tải xuống ... làm cho cuộc sống dễ dàng hơn rất nhiều

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.