J'ai une requête SQL donnée ci-dessous, je veux sélectionner plusieurs valeurs en utilisant l'opérateur like
.
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 de rx_dt
?
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 constructeur de ligne VALUES
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
...
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
id_employé | nom_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
id_employé | nom_employé : ---------- | : ------------ emp10 | Bryan Nelson
Si vous avez besoin des lignes TOP (X) WHERE employee_id LIKE 'emp1%'
plus TOP (X) lignes 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
id_employé | nom_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
id_employé | nom_employé : ---------- | : -------------- emp10 | Bryan Nelson Emp12 | Rosalyn Sanders Emp13 | Rose Tudler Emp30 | Ian McGregor
dbfiddle --- (ici
Je suppose que vous voulez 1 ligne where employee_id like 'emp1%'
et un autre where employee_id like 'emp3%'
. Une façon d'y parvenir est d'utiliser un 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 dans l'union sont garanties d'être disjointes un UNION ALL
peut être utilisé, et cela pourrait être un avantage en termes de performances par rapport à l'utilisation d'un simple 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;