web-dev-qa-db-fra.com

Comment interroger une colonne de table pour des valeurs commençant par un caractère non alphabétique?

Comment les lignes commençant par des caractères non alphabétiques (tous les caractères "spéciaux", y compris les espaces et les traits de soulignement) peuvent-elles être sélectionnées?

Je ne sais pas si cela change quelque chose, mais my_table contiendra également des valeurs commençant par des lettres grecques.

$query = $db->getQuery(true);
$query->clear();
$query
    ->select(array('id', 'last_name', 'first_name'))
    ->from($db->qn('#__my_table'))
    ->where($db->qn('last_name').' LIKE '. $db->q('[^a-zA-Z%]'))
    ->order('last_name, first_name ASC')
    ->setLimit($startrow, '100');
$db->setQuery($query);

Le formulaire de requête est correct et renverra les résultats corrects si je le configure comme suit: $ db-> q ('A%') mon erreur doit donc être avec la regex, mais je ne vois pas où?

MODIFIER APRÈS QUESTION

J'essaie de créer un menu de lettres comme celui-ci A B C D ... Δ ... #. Lorsque vous cliquez sur une lettre, tous les noms de famille commençant par cette lettre s'affichent lorsque vous cliquez sur #. Tous les autres "noms de famille" doivent être renvoyés (les utilisateurs importent les noms de famille de manière à ce qu'ils puissent contenir n'importe quel caractère ou nombre spécial, espace, traits de soulignement). .

Ce code est utilisé lorsque vous cliquez sur #. Il doit donc filtrer tous les noms commençant par English et tous les noms commençant par des caractères grecs. S'il y a un autre moyen de classer ce dont j'ai besoin, merci de le conseiller.

J'ai trouvé PAS REGEXP '. $ Db-> q (' [[A-Za-z%] '))) (CODE MISE À JOUR CI-DESSOUS) fera le plus gros du travail, mais ne filtrera pas les lettres grecques.

$query = $db->getQuery(true);
    $query->clear();
    $query
        ->select(array('id', 'last_name', 'first_name'))
        ->from($db->qn('#__my_table'))
        ->where($db->qn('last_name').' NOT REGEXP '. $db->q('[A-Za-zα-ωΑ-Ω%]'))
        ->order('last_name, first_name ASC')
        ->setLimit($startrow, '100');
    $db->setQuery($query);

RÉSOLU

J'ai pu trouver la regex correcte

$query = $db->getQuery(true);
$query->clear();
$query
    ->select(array('id', 'last_name', 'first_name'))
    ->from($db->qn('#__my_table'))
    ->where($db->qn('last_name').' NOT REGEXP '. $db->q('^[a-z|α-ω]'))
    ->order('last_name, first_name ASC')
    ->setLimit($startrow, '100');
$db->setQuery($query);
1
John

Tout d’abord, avez-vous réellement besoin d’une clause where? Essayez-vous vraiment d’exclure des noms? Quelles sont les exclusions réelles que vous voulez?

Si vous ne voulez pas filtrer les noms, vous pouvez simplement supprimer la clause WHERE de votre requête et obtenir tous les utilisateurs/noms d'utilisateurs.

Deuxièmement, vous ne pouvez pas transmettre de telles expressions régulières dans LIKE. Je parie que votre requête ci-dessus ne renvoie rien du tout. En effet, votre WHERE recherche des noms commençant par [^a-zA-Z] et après cela peut avoir n'importe quoi.

En revanche, le LIKE 'A%' est à la recherche de tous les noms qui commencent par A et qui ont quelque chose après.

Si vous devez faire des regex, alors MySQL fournit REGEXP & NOT REGEXP & RLIKE.

Documentation MySQL:

Ce que vous essayez de filtrer est un peu vague… S'agit-il de noms commençant par des chiffres ou quoi?

Si tel est le cas, il s'agit d'un exemple de requête MySQL avec regex pour filtrer celles-ci:

$query
    ->select(array('id', 'username'))
    ->from($db->qn('#__users'))
    ->where($db->qn('username').' NOT REGEXP '. $db->q('^[0-9]'))
    ->order('username ASC')
    ->setLimit($startrow, '100');
1
FFrewin

Je voudrais affiner la solution du PO intégrée dans la question. Pour que les chercheurs puissent comparer et comprendre ce qui se passe.

$query = $db->getQuery(true)
    ->select($db->qn(["id", "last_name", "first_name"])
    ->from($db->qn("#__my_table"))
    ->where($db->qn("last_name") . " REGEXP " . $db->q("^[^a-zα-ω]"))
    ->order($db->qn(["last_name", "first_name"]))
    ->setLimit((int)$limit, (int)$offset);
$db->setQuery($query);
  • Je ne sais pas que vous avez besoin de clear() alors je le supprime.
  • J'ai ajouté tous les appels inutiles qn() réclamés par Joomla Standards.
  • Votre logique regex recherche des lignes qui ne commencent pas par vos deux plages de lettres. Pour écrire une "classe de caractères refusée, utilisez ^ Juste après le [. À l'intérieur d'une classe de caractères, vous n'utilisez pas de canaux pour séparer des plages de caractères, mais les mettre côte à côte.
  • En utilisant une classe de caractères inversée, vous pouvez supprimer le NOT d’avant REGEXP.
  • Le sens de tri par défaut est ASC, vous pouvez donc omettre cette déclaration de votre requête.
  • Vous avez vos paramètres de début et de limite inversés. La limite devrait venir avant le décalage. https://api.joomla.org/cms-3/classes/JDatabaseQueryLimitable.html#method_setLimit
0
mickmackusa