2015-07-21 57 views
5

选择第一个未使用的ID我在阵列格式的ID名单如下使用MySQL查询

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

我的表记录如下

id email 
1 [email protected] 
2 [email protected] 
10 [email protected] 
13 [email protected] 
15 [email protected] 
20 [email protected] 

我想这个表$ ids数组和比较获取第一个未使用的ID。

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

在此先感谢!

+0

如果我使用IN,它会给出10.bcoz IN查询返回匹配的行。我对么? – Asik

+1

和'NOT IN'' – splash58

+0

耶,IN总是给出匹配的结果 –

回答

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

?>

+0

是的,我想过这个,但有没有办法通过MySQL查询?谢谢您的回答! – Asik

2

说你的表名是emails和你的模型是Email:用雄辩得到IDS,然后从数据库获取你的$ids阵列和IDS之间的差异,最终选择第一种:

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

这是非常昂贵的操作,以防我的表电子邮件有更多的记录。我对么? – Asik

+0

@asik是的。但是增加'where'和提取记录并不困难。这有助于。 –

+0

@ b0s3,在我的情况下,记录会很高。所以KTAnj方法比这更好。无论如何,谢谢Marco。我投了你的快速回答:)和def,它会帮助比较表和较少记录的人。 – Asik

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); 
1
create table t1 (id int, email text); 
insert into t1 values 
(1, '[email protected]'), 
(2, '[email protected]'), 
(10, '[email protected]'), 
(13, '[email protected]'), 
(15, '[email protected]'), 
(20, '[email protected]'); 

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

UPDATE

如果你说

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

仅收到16 :)

0

如果高雅不知道,但你可以使用一个临时表到你的阵列存储与使用的ID在MySQL。然后,你可以查询该临时表与限制1和NOT IN要离开了ID的名单上:

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; 

因此,通过在INSERT INTO与替换值建立在你的代码此查询所有ID在$ ids中的列表,使用implode()或其他。

0

你可以首先从DB获得一个ID的数组用

SELECT GROUP_CONCAT(id) FROM tbl_name 

说你把内容$返回结果,你的ID阵列将

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

,那么你可以简单地

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