Sélectionnez plusieurs valeurs dans LIKE Operator

10

J'ai une requête SQL donnée ci-dessous, je souhaite sélectionner plusieurs valeurs à l'aide de l' likeopérateur.

Ma requête est-elle correcte?

SELECT top 1 employee_id, employee_ident, utc_dt, rx_dt 
FROM       employee
INNER JOIN employee_mdata_history 
ON         employee.ident=employee_mdata_history.employee_ident 
WHERE      employee_id like 'emp1%' , 'emp3%' 
ORDER BY   rx_dt desc

Sinon, quelqu'un peut-il me corriger?

Ma table contient une grande quantité de données commençant par 'emp1'et 'emp3'. Puis-je filtrer le résultat par les 3 premiers "emp1" et les 2 premiers "emp3" en fonction rx_dt?

l.lijith
la source

Réponses:

16

Vous pouvez également essayer la méthode suivante:

SELECT
  x.*
FROM
  (
    VALUES
      ('emp1%', 3),
      ('emp3%', 2)
  ) AS v (pattern, row_count)
  CROSS APPLY
  (  -- your query
    SELECT top (v.row_count)
               employee_id, employee_ident, utc_dt, rx_dt 
    FROM       employee
    INNER JOIN employee_mdata_history
    ON         employee.ident=employee_mdata_history.employee_ident 
    WHERE      employee_id like v.pattern
    ORDER BY   rx_dt desc
  ) AS x
;

Le VALUESconstructeur de lignes représente votre liste de modèles sous forme de tableau, fournissant en outre à chaque modèle le nombre de lignes à récupérer pour ce modèle. L'opérateur CROSS APPLY applique votre requête à chaque ligne de la liste de modèles, c'est-à-dire à chaque modèle, en limitant le nombre de lignes de chaque modèle à la valeur correspondante de la liste de modèles.

En guise de remarque, permettez-moi de saisir cette occasion pour suggérer que vous qualifiez toujours vos colonnes avec l'alias de table dans une requête qui lit à partir de deux tables ou plus. Cela rend votre requête plus facile à lire / à comprendre. Vous pouvez toujours utiliser des alias courts pour éviter de répéter des noms de table potentiellement longs. Par exemple:

SELECT TOP (1)
  e.employee_id,
  h.employee_ident,
  ...
FROM
  dbo.employee AS e
  INNER JOIN dbo.employee_mdata_history AS h
    ON e.ident = h.employee_ident
WHERE
  e.employee_id LIKE ...
ORDER BY
  ...
Andriy M
la source
6

Vous devez utiliser une condition OR / AND:

SELECT TOP (1) 
           employee_id, employee_ident, utc_dt, rx_dt 
FROM       employee
INNER JOIN employee_mdata_history 
ON         employee.ident = employee_mdata_history.employee_ident 
WHERE      employee_id like 'emp1%' 
OR         employee_id like 'emp3%' 
ORDER BY   rx_dt desc;

Jetez un œil à OR (Transact-SQL) sur MS-Docs.

J'ai mis en place un exemple:

create table employees(employee_id varchar(10), employee_name varchar(100));

insert into employees values
('emp10', 'Bryan Nelson'),
('emp12', 'Rosalyn Sanders'),
('emp13', 'Rose Tudler'),
('emp20', 'Julio Gomez'),
('emp30', 'Ian McGregor'),
('emp40', 'Anne Hatt');
GO
SELECT employee_id, employee_name
FROM   employees
WHERE  employee_id LIKE 'emp1%'
OR     employee_id LIKE 'emp3%';
GO
employé_id | Nom de l'employé  
: ---------- | : --------------
emp10 | Bryan Nelson   
emp12 | Rosalyn Sanders
emp13 | Rose Tudler    
emp30 | Ian McGregor   

Gardez à l'esprit que vous utilisez TOP 1, vous obtiendrez une ligne maximum, quel que soit le nombre de conditions que vous utilisez.

SELECT TOP 1 employee_id, employee_name
FROM   employees
WHERE  employee_id LIKE 'emp1%'
OR     employee_id LIKE 'emp3%';
GO
employé_id | Nom de l'employé
: ---------- | : ------------
emp10 | Bryan Nelson

Si vous avez besoin des lignes TOP (X) WHERE employee_id LIKE 'emp1%'et TOP (X), WHERE employee_id LIKE 'emp3%'vous pouvez utiliser deux instructions select jointes à UNION ALL.

SELECT TOP 3 employee_id, employee_name
FROM   employees
WHERE  employee_id LIKE 'emp1%'
UNION ALL
SELECT TOP 1 employee_id, employee_name
FROM   employees
WHERE  employee_id LIKE 'emp3%'
GO
employé_id | Nom de l'employé  
: ---------- | : --------------
emp10 | Bryan Nelson   
emp12 | Rosalyn Sanders
emp13 | Rose Tudler    
emp30 | Ian McGregor   

De plus, je vais ajouter une recherche de modèle, mais cette solution renvoie tous les enregistrements qui correspondent au modèle: LIKE 'emp [13]%'

SELECT employee_id, employee_name
FROM   employees
WHERE  employee_id LIKE 'emp[13]%'
GO
employé_id | Nom de l'employé  
: ---------- | : --------------
emp10 | Bryan Nelson   
emp12 | Rosalyn Sanders
emp13 | Rose Tudler    
emp30 | Ian McGregor   

dbfiddle ici

McNets
la source
2

Je suppose que vous voulez une ligne where employee_id like 'emp1%'et une autre where employee_id like 'emp3%'. Une façon d'y parvenir consiste à utiliser union:

SELECT t1.*
FROM
  ( SELECT top 1 employee_id, employee_ident, utc_dt, rx_dt 
    FROM       employee
    JOIN employee_mdata_history 
        ON employee.ident=employee_mdata_history.employee_ident 
    WHERE employee_id like 'emp1%'
    ORDER BY rx_dt desc
  ) AS t1
UNION ALL
SELECT t2.*
FROM
  (  SELECT top 1 employee_id, employee_ident, utc_dt, rx_dt 
    FROM       employee
    JOIN employee_mdata_history 
        ON employee.ident=employee_mdata_history.employee_ident 
    WHERE employee_id like 'emp3%'
    ORDER BY rx_dt desc
  ) AS t2 ;

Étant donné que les jambes de l'union sont garanties disjointes, un UNION ALLpeut être utilisé, et cela pourrait être un avantage en termes de performances par rapport à l'utilisation d'un seul UNION.

Je crois que SQL-server 2008 prend en charge les fonctions de fenêtre comme row_number (), vous pouvez donc utiliser quelque chose comme:

SELECT employee_id, employee_ident, utc_dt, rx_dt
FROM (
    SELECT employee_id, employee_ident, utc_dt, rx_dt
      , row_number() over (partition by substring(employee_id,1,4)
                           order by rx_dt desc) as rn 
    FROM employee
    JOIN employee_mdata_history 
        ON employee.ident = employee_mdata_history.employee_ident 
    WHERE employee_id like 'emp1%' 
       OR employee_id like 'emp3%'
) as T 
WHERE rn = 1 
ORDER BY rx_dt desc;
Lennart
la source
-2

Vous utilisez TOP(1)et order byclause. Ainsi, vous n'obtiendrez que le premier enregistrement supérieur ordonné par la clause.

Ashmita Jain
la source