2011-04-05 7 views
1

これが正しいかどうかは分かりませんが、私のスクリプトには問題があります。私は、一度のマージであるPHPでデータベースをマージしようとしています。私がやっていることは、本の独特のタイトルのリストをつかんで、そのタイトルの本を見つけてタイプ別にグループ分けし、その結果からそのユニークなタイトルとタイプの本を見つけることです。著作権と出版者。主な問題は、これは長い時間がかかり、mysqlサーバがタイムアウトするということです。 SQLを使ってこれを行うより良い方法はありますか?SQLレコードをマージする

マージの例は、これを次のようになります。

INSERT INTO books (1, 'Some Book', 'Penguin Publishing', '2005', 1); 
INSERT INTO books (2, 'Some Book', 'Penguin Publishing', '2005', 1); 
INSERT INTO books (3, 'Some Book 2', 'Penguin Publishing', '2005', 1); 
INSERT INTO books (4, 'Some Book 2', 'Lion Publishing', '2005', 1); 
INSERT INTO books (5, 'Some Book 2', 'Penguin Publishing', '2005', 2); 
INSERT INTO books (6, 'Some Book 2', 'Penguin Publishing', '2005', 2); 
INSERT INTO books (7, 'Somebody', 'Lion Publishing', '2005', 1); 
INSERT INTO books (8, 'Somebody', 'Lion Publishing', '2007', 1); 
INSERT INTO books (9, 'Somebody', 'Penguin Publishing', '2005', 1); 

IDが1 & 2彼らは1を持っているので)同じタイトル2)同じmaterial_type_id 3)同じ著作権及び4)同じ出版社に参加する必要があります。

PURE SQLまたはマイナーPHPでこれを達成する方法はありますか?

CREATE TABLE books (
    id int(11) NOT NULL AUTO_INCREMENT, 
    title varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, 
    publisher varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, 
    copyright varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, 
    material_type_id int(11) DEFAULT NULL 
    PRIMARY KEY (id), 
    FULLTEXT KEY title (title) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

EDIT私は私は本当に重要な何かを言及するのを忘れてしまったと思い

は、ここに私のデータ構造です。私はIDを使用する必要があるので、単にGROUPクエリを使用することはできません。フィールド「book_id」を持つ「Items」という別のテーブルがあります。私がレコードをGROUPするだけの場合は、孤立したアイテムになります。私は必要なの順序クエリを分割する方法ですので、私はこのような結果に終わる:

id | title | publisher | copyright | material_type_id 
----------------------------------------------------- 
1 'Some Book' 'Penguin Publishing' '2005' 1 
2 'Some Book' 'Penguin Publishing' '2005' 1 
----------------------------------------------------- 
5 'Some Book 2' 'Penguin Publishing' '2005' 2 
6 'Some Book 2' 'Penguin Publishing' '2005' 2 
----------------------------------------------------- 
3 'Some Book 2' 'Penguin Publishing' '2005' 1 
----------------------------------------------------- 

原因、私は最初のグループでこのようなクエリを実行することができます:

UPDATE items SET book_id = 1 WHERE book_id IN (1, 2) 

私はそれが理にかなっていることを願っています。私が説明するのは本当に難しいです。あなたの助けと忍耐力に感謝します。

+0

をアイテムレコードを移動するので、あなただけの重複エントリ(すべてのフィールドと同じ)を除去するために探していますか?そして私は、私の教師がいつもデータベースが可能な限り重い作業をするように言っていることを覚えています。そうすれば、SQL(可能な場合)をお勧めします。 – Ben

+0

誰かがSQLでそれを行う方法の答えを得るためにソーステーブル構造を投稿する必要があります。 –

答えて

1

このクエリは、重複したルールが指定されたブックの1つを除くすべてのコピー(最小ID付き)を保持します。上記を実行している、BEFORE

DELETE FROM A 
using books A 
join (select title,publisher,material_type_id,copyright, MIN(id) keep 
    from books 
    group by title,publisher,material_type_id,copyright 
    having count(*) > 1) B 
    on A.title=B.title 
     and A.publisher=B.publisher 
     and A.material_type_id=B.material_type_id 
     and A.copyright=B.copyright 
     and A.id <> B.keep; 

、(正式にテストされていない)最初の

UPDATE items 
join books A on A.id = items.book_id 
join (select title,publisher,material_type_id,copyright, MIN(id) keep 
    from books 
    group by title,publisher,material_type_id,copyright 
    having count(*) > 1) B 
    on A.title=B.title 
     and A.publisher=B.publisher 
     and A.material_type_id=B.material_type_id 
     and A.copyright=B.copyright 
     and A.id <> B.keep 
set items.book_id = B.keep 
+0

この解決策の問題は、すべての私の 'item'レコードが孤立するということです。 – LordZardeck

+0

あなたは私の救い主です!!!! 2番目のコードブロックは、私が探していたものをEXACLTYでした。今度は最初のコードブロックで解決するつもりですが、次のエラーが表示されます。 [エラー] 1064 - SQL構文にエラーがあります。あなたのMySQLサーバのバージョンに対応するマニュアルをチェックして、正しい構文がどこにあるのかを確認してください。( を選択してください。 グループ別タイトル、mater '2行 – LordZardeck

+0

@LordZardeck/DELETE FROMが必要でした – RichardTheKiwi

関連する問題