获取其列具有相同值的两个连续行的ID

时间:2016-11-28 08:22:14

标签: php mysql

我的MySql表包含以下值。

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);

问题

要求我需要为ids为0的两条记录获取item_type,并且这些行必须是连续的,前提是它们共享相同的Code

所以,例如, 在上表中,所需的ID为532 and 528508 and 495等等,可能会有很多。

更新

上表的示例输出应为数组

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

更新2 当给出code值时,应该获取所需的输出

任何帮助都将受到高度赞赏

2 个答案:

答案 0 :(得分: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   |
+--------+----------+------------+--------+

答案 1 :(得分: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