2015-07-21 24 views
5

Mam listę identyfikatorów w formacie tablicy następującoWybierz pierwszą niewykorzystaną id użyciu kwerendy mysql

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

Mój rekord tabeli następująco

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

Chcę porównać tę tabelę z $ ids tablica i zdobądź pierwszy nieużywany identyfikator.

Dla powyższego przykładu: I expect the result 16. Potrzebuję eleganckiego sposobu/zapytania, aby znaleźć to samo.

Z góry dziękuję!

+0

Jeśli użyję IN, daje to 10. bcoz Zapytanie IN zwraca dopasowane wiersze. mam rację? – Asik

+1

a co z "NOT IN" – splash58

+0

tak, IN zawsze daje dopasowane wyniki –

Odpowiedz

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

tak, myślałem o tym już, ale czy istnieje sposób przez zapytanie mysql? Dziękuję za Twoją odpowiedź! – Asik

2

Wypowiedz nazwa tabeli jest emails i twój model jest Email: użyj wymowny aby uzyskać identyfikatory, a następnie uzyskać różnicę między tablicy $ids i identyfikatorów z db wreszcie odebrać pierwszy:

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

to jest bardzo droga operacja w przypadku mój stół e-mail ma więcej zapisów. mam rację? – Asik

+0

@asik To prawda. Ale dodanie "gdzie" i pobieranie rekordów nie jest trudne. To pomaga. –

+0

@ b0s3, w moim przypadku rekordy będą wysokie. Tak więc podejście KTAnj jest lepsze niż to. w każdym razie, dziękuję Marco. Głosowałem za szybką odpowiedzią :) i def, pomoże to komuś, kto porównuje tabelę z mniejszą ilością rekordów. – Asik

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

następnie można porównać ze swoimi polami

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

wynikowych

16, 25, 28, 34, 40, 45 

DEMO

UPDATE

Jeśli powiesz

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

otrzymasz tylko 16 :)

0

Nie wiem, czy eleganckie, ale można użyć tabeli temp do przechowywania tablicę z używanymi identyfikatorami w MySQL. Następnie można kwerendę temp tabeli z limitem 1 i NOT IN na liście identyfikatorami, które chcesz pominąć:

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; 

Więc zbudowania tej kwerendy w kodzie poprzez zastąpienie wartości w INSERT INTO z lista wszystkich identyfikatorów w $ ids, przy użyciu metody implode() lub czegoś podobnego.

0

Można najpierw uzyskać tablicę identyfikatorów z DB z

SELECT GROUP_CONCAT(id) FROM tbl_name 

powiedzieć umieścić treść powrócił w $ rezultacie swoją tablicę identyfikatorów będzie

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

to możesz po prostu

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