使用mysql查询选择第一个未使用的id

时间:2015-07-21 10:07:54

标签: php mysql laravel

我有数组格式的ID列表,如下所示

$ids = [10, 13, 16, 20, 25, 28, 34, 40, 45];

我的表记录如下

id  email
1   abc@gmail.com
2   xyz@yahoo.com
10  jhs@gmail.com
13  cds@gmail.com
15  gfh@gmail.com
20  dsf@gmail.com

我想将此表与$ ids数组进行比较,并获取第一个未使用的ID。

对于上面的示例,I expect the result 16。我需要优雅的方式/查询来找到相同的。

提前致谢!

7 个答案:

答案 0 :(得分:2)

假设您的表名为emails且您的模型为Email:使用Eloquent获取 ID ,然后获取$ids数组与来自db的 ids ,最后选择第一个:

$dbIds = Email::lists('id');
$diff = array_diff($ids, $dbIds);
$first = array_shift($diff);

答案 1 :(得分:2)

<?php
foreach($ids as $id){
   $result = DB::table($table)->where('id', '=', $id)->get();
   if($result && count($result){
        continue;
   }
   echo 'First unused id :'. $id;
   break;
}

&GT;

答案 2 :(得分:1)

create table t1 (id int,  email text);
insert into t1 values
(1,   'abc@gmail.com'),
(2,  'xyz@yahoo.com'),
(10,  'jhs@gmail.com'),
(13,  'cds@gmail.com'),
(15,  'gfh@gmail.com'),
(20,  'dsf@gmail.com');

create  table t2 (id int);
insert into t2 values (10), (13), (16), (20), (25), (28), (34), (40), (45);
select t2.id from t2 where t2.id not in (select id from t1)

结果

16, 25, 28, 34, 40, 45

DEMO

<强>更新

如果你说

select min(t2.id) from t2 where t2.id not in (select id from t1)

你只收到16 :)

答案 3 :(得分:0)

   $sql = 'SELECT field WHERE field IN ' . implode( ',', $ids) . ' );';
    $result = $db->query($sql);
    $found = array();
    while ($row = $result->fetch_assoc()) {
        $found[] = $row['field'];
    }

然后你可以与你的领域进行比较

$not_found = array_diff($ids, $found);

答案 4 :(得分:0)

不确定是否优雅,但您可以使用临时表来存储MySQL中使用过的ID的数组。然后你可以在你想要遗漏的ID列表中查询限制1和NOT IN的临时表:

CREATE TEMPORARY TABLE IF NOT EXISTS tmp_all_ids (`id` INT(11));
INSERT INTO `tmp_all_ids` (`id`) VALUES (2), (5), (3);
SELECT `id` FROM `tmp_used_ids` WHERE `id` NOT IN (SELECT `id` FROM `table_with_used_ids`) LIMIT 1;

因此,使用implode()或其他东西,将INSERT INTO中的值替换为$ ids中所有ID的列表,在代码中构建此查询。

答案 5 :(得分:0)

您可以先使用

从数据库中获取ID数组
SELECT GROUP_CONCAT(id) FROM tbl_name

假设您将$ result中返回的内容放入,您的ID数组将为

$db_ids = explode(',', $result);

然后你可以简单地

$diff = array_diff($ids, $db_ids);
$first_unused_id = min($diff);

答案 6 :(得分:0)

更高的性能和优化的代码:

    // Occupying of unused IDs.
    $used_ids = Dua::pluck('id');
    $prev_id = 0;
    foreach ($used_ids as $used_id) {
      if (1 < ($used_id - $prev_id)) {
        $dua->id = $prev_id + 1;
        break;
      }
      
      $prev_id = $used_id;
    }