简体   繁体   中英

simple select statement inside foreach loop

I have this PHP snippet below which I'm using to check the gender of names from a table, inside a foreach loop, as a measure of optimization, I have included LIMIT 1 to the select statement. When I use EXPLAIN on the select statement, indexes were applied and value under row column is 1?

Are there other ways I can further improve this?

foreach ($tmp as $key => $value) {
    foreach ($value as $name) {
        $statement = $dbh->prepare('SELECT gender FROM tbl WHERE names = :n LIMIT 1');
        $statement->execute(['n' => trim($name)]);
        $user = $statement->fetch(PDO::FETCH::ASSOC);
        if ($user["gender"] == "F")
            $f++;
        else if ($user["gender"] == "M")
            $m++;
        else
            $mf++;
    }
}

It would be easier to create a comma-separated list of names, then drop it into something like the following query:

SELECT sum(gender = "F") 'females', sum(gender == "M") 'males', sum(gender != "F" && gender != "M") 'other'    
FROM tbl 
WHERE names IN (:list);

then,

$m = $user["males"];
$f = $user["females"];
$mf = $user["other"];

etc.

Why do looped queries when one will suffice? :)

I assume you need to get a gender statistic? Then you could do it without cycles directly with SQL query like so:

$statement = $dbh->prepare(
    "SELECT 
         count(CASE WHEN gender = 'M' THEN id END) as m, 
         count(CASE WHEN gender = 'F' THEN id END) as f, 
         count(CASE WHEN gender IS NULL THEN id END) as mf 
     FROM tbl
     WHERE names IN (?)"
);
$statement->bindValue([$name_array], [\Doctrine\DBAL\Connection::PARAM_STR_ARRAY]);
$statement->execute();
$genderStatistics = $statement->fetch(PDO::FETCH::ASSOC);

It should work faster.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM