Quelle serait la manière la plus élégante d'obtenir toutes les entrées d'un enregistrement donné qui sont «plus longues», «plus courtes» ou identiques.

Voici un exemple:

Tableau 1

"1234567"   
"123456"    
"12345"   
"12346"  
"12355"    
"123"   
"12" 

Supposons que l'original soit "12345". Ensuite, je voudrais sélectionner "1234567", "123456" (les versions plus longues), "123", "12" (Les versions plus courtes) ainsi que l'original "12345" du tableau 1, mais PAS "12346" et " 12355 ".

Je sais comment le faire en utilisant deux requêtes, mais est-ce possible de sélectionner les enregistrements avec une seule requête?

1
mohofe 27 janv. 2019 à 16:47

3 réponses

Meilleure réponse

Vous pouvez utiliser deux conditions LIKE:

select *
from t
where t.str like '12345%'
   or '12345' like concat(t.str, '%')

Démo: https://rextester.com/FGKMC15900

Lire comme suit: sélectionnez toutes les lignes dont la valeur de colonne commence par la chaîne "d'origine" ou la chaîne "d'origine" commence par la valeur de colonne.

0
Paul Spiegel 27 janv. 2019 à 19:55

Vous pouvez utiliser les éléments suivants:

SELECT col1, 
    CASE WHEN col1 LIKE '12345%' AND LENGTH(col1) > LENGTH('12345') THEN 'longer' 
         WHEN col1 LIKE '12345%' AND LENGTH(col1) = LENGTH('12345') THEN 'same' 
         WHEN '12345' LIKE CONCAT(col1, '%') AND LENGTH(col1) < LENGTH('12345') THEN 'shorter' 
         ELSE '' END AS compared_length
FROM test

démo: https://www.db-fiddle.com / f / jzaz6GpfgZ3iBcnjiApybL / 0

1
Sebastian Brosch 27 janv. 2019 à 14:04

Voici une version alternative, qui utilise une clause WHERE avec un REGEXP pour filtrer les enregistrements non pertinents; alors, il ne reste plus qu'à comparer les longueurs des chaînes:

SELECT
    col1,
    CASE 
        WHEN LENGTH(col1) > LENGTH(@match) THEN 'longer'
        WHEN LENGTH(col1) < LENGTH(@match) THEN 'shorter'
        ELSE 'same'
    END result
FROM mytable
WHERE col1 REGEXP @match OR @match REGEXP col1

Démo sur DB Fiddle:

SET @match = '12345';

SELECT
    col1,
    CASE 
        WHEN LENGTH(col1) > LENGTH(@match) THEN 'longer'
        WHEN LENGTH(col1) < LENGTH(@match) THEN 'shorter'
        ELSE 'same'
    END result
FROM mytable
WHERE col1 REGEXP @match OR @match REGEXP col1;
| col1    | result  |
| ------- | ------- |
| 1234567 | longer  |
| 123456  | longer  |
| 12345   | same    |
| 123     | shorter |
| 12      | shorter |
0
GMB 27 janv. 2019 à 14:39