2013-05-08 30 views
8

Tôi có một bảng trông như thế này:Kết hợp hai truy vấn để kiểm tra các bản sao trong MySQL?

Number | Name 
--------+-------- 
123  | Robert 

Đây là những gì tôi muốn làm:

Nếu Số là đã có trong cơ sở dữ liệu, không chèn một kỷ lục mới.

Nếu số không nằm trong databse, nhưng tên là, tạo tên mới và chèn nó. Vì vậy, ví dụ, nếu tôi có một kỷ lục có chứa 123 cho NumberBob cho Name, tôi không muốn để chèn nó, nhưng nếu tôi có được một kỷ lục có chứa 456 cho NumberRobert cho name, tôi sẽ chèn 456Robert1 . Tôi sẽ kiểm tra các bản sao riêng lẻ như:

SELECT * FROM Person where Number = 123; 

//If number is not found 
SELECT * FROM Person where Name = 'Robert'; 

//If name is found, add a number to it. 

Có cách nào tôi có thể kết hợp hai câu?

Trả lời

9

Thực tế có hai vấn đề trong câu hỏi của bạn. Vấn đề đầu tiên là làm cho cột Number duy nhất và cột thứ hai là tăng cột Name bằng cách nối thêm một số nếu nó đã tồn tại.

ĐẦU PHẦN

Kể từ khi số là UNIQUE, thực thi một chế UNIQUE trên cột. Nó có thể là PRIMARY KEY hoặc UNIQUE KEY.

Nếu cột không có KEY và bạn muốn làm cho nó PRIMARY, đây là ALTER tuyên bố:

ALTER TABLE TableName ADD CONSTRAINT tb_pk PRIMARY KEY (Number) 

nhưng nếu bạn chỉ muốn nó được UNIQUE và không phải là khóa chính,

ALTER TABLE TableName ADD CONSTRAINT tb_uq UNIQUE (Number) 

THỨ HAI PHẦN

Bạn thực sự có thể làm điều đó mà không sử dụng tham gia.

INSERT INTO TableName(Number, Name) 
SELECT 124 AS Number, 
     CONCAT('Robert', COALESCE(MAX(CAST(REPLACE(Name, 'Robert', '0') AS UNSIGNED)) + 1,'')) AS Name 
FROM TableName 
WHERE Name LIKE 'Robert%' 

Một số chi tiết:

khi giá trị được cung cấp trên cột Number đã tồn tại, nó sẽ ném ra một lỗi từ cột là độc nhất. Tôi đã đọc một bình luận từ một bài viết đã xóa nói rằng: "..Number không phải là duy nhất, nhưng nếu nó tồn tại, tôi không muốn nhập một bản ghi." - không có ý nghĩa gì nếu bạn không muốn thêm tính duy nhất trên cột. Làm thế nào bạn sẽ biết nếu số đã tồn tại hay không? Làm một kiểm tra nhỏ cho sự tồn tại của Number cảm thấy như một chi phí nhỏ cho tôi. Vì vậy, đề nghị tốt nhất của tôi là để thực thi tính độc đáo.

+1

@ J.W. ít nhất hãy cho chúng tôi ** một chút thời gian để suy nghĩ: P, bởi vì câu trả lời của bạn thật tuyệt vời đến mức chúng tôi không thể nghĩ ra bất kỳ câu trả lời nào tốt hơn. Ở giữa cho phép tôi kết nối với bạn ** FB ** :) – Luv

+0

Khi tôi chèn 'Rober' thay vì' Robert', lỗi kết quả truy vấn của bạn: 'Cắt dữ liệu: Cắt ngắn giá trị INTEGER không chính xác: '0t'', trong khi Rober là mới Tên và hợp lệ. – ahoo

+0

phần thứ hai là thực sự tuyệt vời :) +1 – fthiella

1
SELECT * FROM Person WHERE Number = 123 OR Name = 'Robert' 

Tôi chưa từng làm việc với SQL trong một thời gian, vì vậy đây có thể sai;)

Edit:

$number = 123; 
$name = 'Robert'; 
$query = mysql_query("SELECT * FROM Person WHERE Number = $number OR Name = '$name' "); 

if (mysql_num_rows($query) == 0) { 
//-> Add your record, it's unused 
} else if (mysql_result($query, 0, 'number') == $number && mysql_result($query, 0, 'name' == $name)) { 
//combination of number and name already exists -> modify name and add record 
} else { 
echo "Number is used by another name"; 
} 
+0

Có cách nào để chỉ trả lại nếu chỉ khi Số không tồn tại, về cơ bản tôi không muốn thực hiện HOẶC, nhưng tôi vẫn muốn nhận Tên ngay cả khi Số không tồn tại , vì vậy nếu tôi làm một truy vấn như 'SELECT * FROM Person WHERE Number = 123 AND Name = 'Bob'', điều này sẽ không trả về gì cả, nhưng tôi không muốn điều đó, tôi vẫn muốn trả lại một bản ghi với Name. – Xaisoft

+0

Tôi nghĩ rằng điều này làm những gì bạn muốn.$ number = 123; $ name = 'Robert'; $ query = mysql_query ("SELECT * FROM Person WHERE Number = $ number OR Tên = '$ name'"); nếu (mysql_num_rows ($ query) == 0) { // -> Thêm hồ sơ của bạn, nó không được sử dụng } else { if (mysql_result ($ query, 0, 'number') == $ number && mysql_result ($ query, 0, 'name' == $ name)) { // kết hợp số và tên đã tồn tại -> sửa đổi tên và thêm bản ghi } else { echo "Số được sử dụng bởi tên khác"; } } –

1

Sử dụng truy vấn này, cho chèn hàng [123, 'Robert']. nếu bạn muốn chèn các giá trị khác, thay đổi 123 & Robert giá trị trong truy vấn dưới đây:

insert into Person (Number,Name) 
select 123, IF(mn.MaxNumber is NULL,'Robert',concat('Robert',mn.MaxNumber+1)) 
from (SELECT 'foo') foo 
left JOIN (select max(CONVERT(SUBSTR(Name,LENGTH('Robert')+1),UNSIGNED)) `MaxNumber` 
      from person where name rlike '^Robert[0-9]*$') mn on 1=1 
where Not Exists (select * from Person where Number=123) 

LƯU Ý: nếu Robert tồn tại trong bảng, trên truy vấn chèn Robert1. nếu Robert1 tồn tại, nó chèn Robert2, v.v.

+0

* "Tôi nghĩ câu trả lời của tôi là tốt nhất, vì vậy tôi tự thưởng cho mình tiền thưởng." * - câu trả lời đã xóa của bạn. bạn có nghĩ về buổi biểu diễn không? –

+0

@JW 웃, Câu trả lời của tôi phù hợp khi chúng tôi không muốn thực thi ràng buộc 'UNIQUE' trên cột. Bởi vì người hỏi @Xaisoft, không nói về hạn chế 'UNIQUE'. – ahoo

1

đặt cả số và tên duy nhất.

ALTER TABLE `person` ADD UNIQUE (`number` ,`name`); 

Bây giờ bạn có thể thực hiện chèn với ON DUPLICATE

INSERT INTO `person` (`number`, `name`, `id`) VALUES ('322', 'robert', 'NULL')  ON DUPLICATE KEY UPDATE `id`='NULL'; 

Đối với phụ thêm một số sau khi tên tôi sẽ đề nghị sử dụng cột autoincrement để thay thế.

0
insert into Person (Number,Name) 
select 123, IF(mn.MaxNumber is NULL,'Robert',concat('Robert',mn.MaxNumber+1)) 
from (SELECT 'foo') foo 
left JOIN (select max(CONVERT(SUBSTR(Name,LENGTH('Robert')+1),UNSIGNED)) `MaxNumber` 
      from person where name rlike '^Robert[0-9]*$') mn on true 
where Not Exists (select * from Person where Number=123) 
Các vấn đề liên quan