2008-10-09 55 views
39

Làm cách nào để tạo một dãy các số liên tiếp (một trên mỗi dòng) từ truy vấn MySQL để tôi có thể chèn chúng vào một bảng?Tạo một dãy số trong MySQL

Ví dụ:

nr 
1 
2 
3 
4 
5 

Tôi muốn chỉ sử dụng MySQL cho điều này (không PHP hoặc các ngôn ngữ khác).

+0

Bạn có muốn thêm bản ghi này vào các bản ghi hiện có hoặc một bảng hoàn toàn mới không? – Sklivvz

+0

Đây sẽ là reccords mới. – nicudotro

+1

Tại sao bạn không thể sử dụng cột auto_increment? – Rob

Trả lời

25

Nếu bạn cần bản ghi trong bảng và bạn muốn tránh các vấn đề tương tranh, dưới đây là cách thực hiện.

Trước tiên, bạn tạo một bảng trong đó để lưu trữ hồ sơ của bạn

CREATE TABLE `incr` (
    `Id` int(11) NOT NULL auto_increment, 
    PRIMARY KEY (`Id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

Thứ hai tạo ra một thủ tục lưu trữ như thế này:

DELIMITER ;; 
CREATE PROCEDURE dowhile() 
BEGIN 
    DECLARE v1 INT DEFAULT 5; 
    WHILE v1 > 0 DO 
    INSERT incr VALUES (NULL); 
    SET v1 = v1 - 1; 
    END WHILE; 
END;; 
DELIMITER ; 

Cuối cùng gọi SP:

CALL dowhile(); 
SELECT * FROM incr; 

quả

Id 
1 
2 
3 
4 
5 
5
DECLARE i INT DEFAULT 0; 

WHILE i < 6 DO 
    /* insert into table... */ 
    SET i = i + 1; 
END WHILE; 
54

Dưới đây là một cách để làm điều đó dựa trên cơ sở không có vòng lặp. Điều này cũng có thể được đưa vào chế độ xem để sử dụng lại. Ví dụ cho thấy việc tạo chuỗi từ 0 đến 999, nhưng tất nhiên, nó có thể được sửa đổi cho phù hợp.

INSERT INTO 
    myTable 
    (
    nr 
    ) 
SELECT 
    SEQ.SeqValue 
FROM 
(
SELECT 
    (HUNDREDS.SeqValue + TENS.SeqValue + ONES.SeqValue) SeqValue 
FROM 
    (
    SELECT 0 SeqValue 
    UNION ALL 
    SELECT 1 SeqValue 
    UNION ALL 
    SELECT 2 SeqValue 
    UNION ALL 
    SELECT 3 SeqValue 
    UNION ALL 
    SELECT 4 SeqValue 
    UNION ALL 
    SELECT 5 SeqValue 
    UNION ALL 
    SELECT 6 SeqValue 
    UNION ALL 
    SELECT 7 SeqValue 
    UNION ALL 
    SELECT 8 SeqValue 
    UNION ALL 
    SELECT 9 SeqValue 
    ) ONES 
CROSS JOIN 
    (
    SELECT 0 SeqValue 
    UNION ALL 
    SELECT 10 SeqValue 
    UNION ALL 
    SELECT 20 SeqValue 
    UNION ALL 
    SELECT 30 SeqValue 
    UNION ALL 
    SELECT 40 SeqValue 
    UNION ALL 
    SELECT 50 SeqValue 
    UNION ALL 
    SELECT 60 SeqValue 
    UNION ALL 
    SELECT 70 SeqValue 
    UNION ALL 
    SELECT 80 SeqValue 
    UNION ALL 
    SELECT 90 SeqValue 
    ) TENS 
CROSS JOIN 
    (
    SELECT 0 SeqValue 
    UNION ALL 
    SELECT 100 SeqValue 
    UNION ALL 
    SELECT 200 SeqValue 
    UNION ALL 
    SELECT 300 SeqValue 
    UNION ALL 
    SELECT 400 SeqValue 
    UNION ALL 
    SELECT 500 SeqValue 
    UNION ALL 
    SELECT 600 SeqValue 
    UNION ALL 
    SELECT 700 SeqValue 
    UNION ALL 
    SELECT 800 SeqValue 
    UNION ALL 
    SELECT 900 SeqValue 
    ) HUNDREDS 
) SEQ 
+12

Thats đổi mới –

42

Dưới đây là phiên bản một kỹ sư phần cứng của dung dịch Pittsburgh DBA:

SELECT 
    (TWO_1.SeqValue + TWO_2.SeqValue + TWO_4.SeqValue + TWO_8.SeqValue + TWO_16.SeqValue) SeqValue 
FROM 
    (SELECT 0 SeqValue UNION ALL SELECT 1 SeqValue) TWO_1 
    CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 2 SeqValue) TWO_2 
    CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 4 SeqValue) TWO_4 
    CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 8 SeqValue) TWO_8 
    CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 16 SeqValue) TWO_16; 
+3

Được thực hiện tốt đẹp ở đó. –

+0

Mục đích là tạo một chuỗi có kích thước chỉ được biết đến trong thời gian chạy và không cần sử dụng SQL động. –

12

Hãy nói rằng bạn muốn chèn số từ 1 đến 100 vào bảng của bạn. Miễn là bạn có một số bảng khác có ít nhất là nhiều hàng (không quan trọng nội dung của bảng), thì đây là phương pháp ưa thích của tôi:

INSERT INTO pivot100 
SELECT @ROW := @ROW + 1 AS ROW 
FROM someOtherTable t 
join (SELECT @ROW := 0) t2 
LIMIT 100 
; 

Muốn một phạm vi bắt đầu bằng một thứ khác 1? Chỉ cần thay đổi những gì @ROW được thiết lập để tham gia.

+0

Điều này có vẻ như một hack, nhưng tôi cần khoảng 7.000 con số và tôi đã có một bảng với 70.000 hàng, do đó, nó hoạt động tuyệt vời! – cjm

6

Như tất cả các bạn hiểu, điều này là khá hacky để sử dụng một cách cẩn thận

SELECT id % 12 + 1 as one_to_twelve FROM any_large_table group by one_to_twelve 
+0

Bạn đã thử nghiệm điều này chưa? – Kermit

+0

đây chỉ là những gì tôi cần: Tôi có một bảng lớn với id tăng tự động xác định cấu trúc, tôi muốn tìm ra nhiều hàng đã bị xóa và có bao nhiêu id có thể được sử dụng lại withot cho phép mysql tự động tạo khóa. Cảm ơn rất nhiều! – mikewasmike

0

Các "ngắn nhất" cách tôi biết (trong MySQL) để tạo ra một bảng với một chuỗi dài là (chữ thập) tham gia vào một bảng hiện có với chính nó. Vì bất kỳ (phổ biến) máy chủ MySQL có bảng information_schema.COLUMNS tôi sẽ sử dụng nó:

DROP TABLE IF EXISTS seq; 
CREATE TABLE seq (i MEDIUMINT AUTO_INCREMENT PRIMARY KEY) 
    SELECT NULL AS i 
    FROM information_schema.COLUMNS t1 
    JOIN information_schema.COLUMNS t2 
    JOIN information_schema.COLUMNS t3 
    LIMIT 100000; -- <- set your limit here 

thường người ta tham gia nên có đủ để tạo ra qua hàng 1M - Nhưng thêm một tham gia sẽ không làm tổn thương :-) - Chỉ cần làm không quên đặt giới hạn.

Nếu bạn muốn bao gồm 0, bạn nên "xóa" thuộc tính AUTO_INCEMENT.

ALTER TABLE seq ALTER i DROP DEFAULT; 
ALTER TABLE seq MODIFY i MEDIUMINT; 

Bây giờ bạn có thể chèn 0

INSERT INTO seq (i) VALUES (0); 

và tiêu cực số cũng

INSERT INTO seq (i) SELECT -i FROM seq WHERE i <> 0; 

Bạn có thể xác nhận những con số với

SELECT MIN(i), MAX(i), COUNT(*) FROM seq; 
0

Ý tưởng tôi muốn chia sẻ không phải là một sự tái xuất chính xác sponse cho câu hỏi nhưng có thể hữu ích cho một số vì vậy tôi muốn chia sẻ nó.

Nếu bạn thường xuyên chỉ cần một số lượng giới hạn các số thì có thể có lợi khi tạo bảng với các số bạn có thể cần và chỉ cần sử dụng bảng đó mỗi lần. Ví dụ:

CREATE TABLE _numbers (num int); 
INSERT _numbers VALUES (0), (1), (2), (3), ...; 

Chỉ có thể áp dụng nếu bạn cần số dưới giới hạn hợp lý nhất định, do đó, không sử dụng số này để tạo chuỗi 1 ... 1 triệu nhưng có thể dùng cho số 1 ... 10k, ví dụ.

Nếu bạn có danh sách các số trong bảng _numbers sau đó bạn có thể viết các truy vấn như thế này, để đạt được các đặc điểm cá nhân của một chuỗi:

SELECT number, substr(name, num, 1) 
    FROM users 
    JOIN _numbers ON num < length(name) 
    WHERE user_id = 1234 
    ORDER BY num; 

Nếu bạn cần số lượng lớn hơn 10k sau đó bạn có thể tham gia bảng cho chính nó:

SELECT n1.num * 10000 + n2.num 
    FROM _numbers n1 
    JOIN _numbers n2 
    WHERE n1 < 100 
    ORDER BY n1.num * 10000 + n2.num; -- or just ORDER BY 1 meaning the first column 
Các vấn đề liên quan