2016-11-28 10 views
0

次の値を持つMySqlテーブルがあります。列が同じ値を持つ2つの連続する行のIDを取得する

id model category Code item_type 
-------------------------------------- 
543 XYZ  PQR  ABC12  0 
535 XYZ  PQR  ABC12  1 
532 XYZ  PQR  ABC12  0 
528 XYZ  PQR  ABC12  0 
524 XYZ  PQR  ABC12  1 
518 XYZ  PQR  ABC12  0 
515 XYZ  PQR  ABC12  1 
510 XYZ  PQR  ABC12  0 
508 XYZ  PQR  QRP24  0 
495 XYZ  PQR  QRP24  0 
-- --  --   --  -- 

例スキーマとデータ

CREATE TABLE `test_table` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `model` varchar(5) DEFAULT NULL, 
    `category` varchar(5) DEFAULT NULL, 
    `code` varchar(5) DEFAULT NULL, 
    `item_tpe` tinyint(1) DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=544 DEFAULT CHARSET=utf8; 

insert into `test_table`(`id`,`model`,`category`,`code`,`item_tpe`) values (495,'XYZ','PQR','QRP24',0); 
insert into `test_table`(`id`,`model`,`category`,`code`,`item_tpe`) values (508,'XYZ','PQR','QRP24',0); 
insert into `test_table`(`id`,`model`,`category`,`code`,`item_tpe`) values (510,'XYZ','PQR','ABC12',0); 
insert into `test_table`(`id`,`model`,`category`,`code`,`item_tpe`) values (515,'XYZ','PQR','ABC12',1); 
insert into `test_table`(`id`,`model`,`category`,`code`,`item_tpe`) values (518,'XYZ','PQR','ABC12',0); 
insert into `test_table`(`id`,`model`,`category`,`code`,`item_tpe`) values (524,'XYZ','PQR','ABC12',1); 
insert into `test_table`(`id`,`model`,`category`,`code`,`item_tpe`) values (528,'XYZ','PQR','ABC12',0); 
insert into `test_table`(`id`,`model`,`category`,`code`,`item_tpe`) values (532,'XYZ','PQR','ABC12',0); 
insert into `test_table`(`id`,`model`,`category`,`code`,`item_tpe`) values (535,'XYZ','PQR','ABC12',1); 
insert into `test_table`(`id`,`model`,`category`,`code`,`item_tpe`) values (543,'XYZ','PQR','ABC12',0); 

要件は、私がitem_type 0であり、これらの行が連続している必要があり、これらの2つのレコードのidsをフェッチする必要があるということです問題、同じものを共有している場合はCodeとなります。

したがって、上記表の の場合、必要なIDは532 and 528,508 and 495などとなります。

更新

上記の表のサンプル出力は

[532,528] if `code='ABC12'` and `[508, 495]` if the `code='QRP24'` 

アレイであるべきアップデート2 code値を

どれでも助けを与えられたとき、所望の出力が取り出されなければなりません

+0

"連続"とはどういう意味ですか?あなたはどのような注文をしていますか、ID DESC? – 2oppin

+0

サンプル出力も投稿できますか? –

+0

@ 2oppin、IDは降順で「連続」です。ここでは、「item_type = 0」を持ち、同じコード値を持つ2つの行が続きます。 – WatsMyName

答えて

1

変数を使用すると、前の行を追跡することができます。それはMySQLでかなりではありませんが、これは動作します:

SELECT id, lastid, code FROM (
    SELECT 
     id, 
     code, 
     item_tpe, 
     @last_id as lastid, 
     @last_code as lastcode, 
     @last_item_tpe as lastitemtpe, 
     @last_id:=id, 
     @last_code:=code, 
     @last_item_tpe:=item_tpe 
    FROM 
     test_table, 
     (select 
      @last_id := 0, 
      @last_code := "", 
      @last_item_tpe:=0 
     ) SQLVars 
    ORDER BY code, id 
) a 
WHERE 
    a.code = a.lastcode 
    AND a.item_tpe = 0 
    AND a.lastitemtpe = 0 
+0

ありがとうございますが、正しく動作しません。すべての有効な行がフェッチされません。 – WatsMyName

+0

動作しない例を教えてもらえますか?あなたが提供したテストデータに対して、期待される2つのペアが返されます。 – fafl

+0

ちょっと、ここにデータをテストするためのリンクがあり、それをmediafireにアップロードしました - http://www.mediafire.com/file/xv6yme6fswvybqu/testdata.sql – WatsMyName

1

いくつかの方法があります。これらの線に沿って何かでも仕事ができる

CREATE TABLE `test_table` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `code` varchar(5) DEFAULT NULL, 
    `item_tpe` tinyint(1) DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=544 DEFAULT CHARSET=utf8; 

insert into `test_table`(`id`,`code`,`item_tpe`) values 
(495,'QRP24',0), 
(508,'QRP24',0), 
(510,'ABC12',0), 
(515,'ABC12',1), 
(518,'ABC12',0), 
(524,'ABC12',1), 
(528,'ABC12',0), 
(532,'ABC12',0), 
(535,'ABC12',1), 
(543,'ABC12',0); 

SELECT a.* 
    FROM 
    (SELECT x.* 
      , MIN(y.id) next 
     FROM test_table x 
     JOIN test_table y 
      ON y.id > x.id 
     GROUP 
      BY x.id 
    ) a 
    JOIN test_table b 
    ON b.id = a.next 
    AND b.code = a.code 
    AND b.item_tpe = a.item_tpe 
WHERE a.item_tpe = 0; 
+-----+-------+----------+------+ 
| id | code | item_tpe | next | 
+-----+-------+----------+------+ 
| 495 | QRP24 |  0 | 508 | 
| 528 | ABC12 |  0 | 532 | 
+-----+-------+----------+------+ 

...

SELECT * FROM 
(
SELECT x.* 
    , CASE WHEN @prev_code = x.code THEN 
     CASE WHEN @prev_item_tpe = item_tpe THEN @status:='true'ELSE @status:='false' END 
      ELSE @status := 'false'END status 
    , @prev_code := x.code 
    , @prev_item_tpe := x.item_tpe 
    FROM test_table x 
    , (SELECT @prev_code := null, @prev_item_tpe := null, @status := null) vars 
ORDER 
    BY x.id 
) a 
WHERE status = 'true' AND item_tpe = 0; 

編集:ここでは一つだあなたの拡大データセットのクイックテストは、両方のクエリが同じ行を返すことが明らかになった...

SELECT a.id  
    , a.item_tpe 
    , a.code  
    , a.next 
    FROM 
    (SELECT x.* 
      , MIN(y.id) next 
     FROM test_table x 
     JOIN test_table y 
      ON y.id > x.id 
     GROUP 
      BY x.id 
    ) a 
    JOIN test_table b 
    ON b.id = a.next 
    AND b.code = a.code 
    AND b.item_tpe = a.item_tpe 
WHERE a.item_tpe = 0; 
+--------+----------+------------+--------+ 
| id  | item_tpe | code  | next | 
+--------+----------+------------+--------+ 
| 491209 |  0 | 3066754917 | 491210 | 
| 491210 |  0 | 3066754917 | 491211 | 
| 491211 |  0 | 3066754917 | 491212 | 
+--------+----------+------------+--------+ 

SELECT a.id  
    , a.item_tpe 
    , a.code  
    , a.status 
    FROM 
(
SELECT x.* 
    , CASE WHEN @prev_code = x.code THEN 
     CASE WHEN @prev_item_tpe = item_tpe THEN @status:='true'ELSE @status:='false' END 
      ELSE @status := 'false'END status 
    , @prev_code := x.code 
    , @prev_item_tpe := x.item_tpe 
    FROM test_table x 
    , (SELECT @prev_code := null, @prev_item_tpe := null, @status := null) vars 
ORDER 
    BY x.id 
) a 
WHERE status = 'true' AND item_tpe = 0; 
+--------+----------+------------+--------+ 
| id  | item_tpe | code  | status | 
+--------+----------+------------+--------+ 
| 491210 |  0 | 3066754917 | true | 
| 491211 |  0 | 3066754917 | true | 
| 491212 |  0 | 3066754917 | true | 
+--------+----------+------------+--------+ 
+0

ありがとうございます。最初のソリューションはデータが少ない場合に機能しますが、大規模なテーブルの場合はクエリの実行に永遠にかかりました。 2番目の解決策は1つのIDを取得するだけで、別の関連IDは取得されません。たとえば、最初の解決策では「次へ」のようになります。 – WatsMyName

+0

(コード、タイプ)のインデックスはかなり速いと思いました。 – Strawberry

+0

テーブル内に10000行しかない場合はさらに遅くなります – WatsMyName

関連する問題