在LIKE运算子中选择多个值


10

我在下面给出了一个SQL查询,我想使用like运算符选择多个值。

我的查询正确吗?

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

如果没有,谁能纠正我?

我的表格包含大量以'emp1'和开头的数据'emp3'。我可以基于前3个“ emp1”和前2个“ emp3”过滤结果rx_dt吗?

Answers:


16

或者,您可以尝试以下方法:

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
;

VALUES行表示构造你的模式列表,表,另外与行数提供每个图案以检索模式。CROSS APPLY运算符将您的查询应用于模式列表的每一行,即应用于每个模式,从而将每个模式的行数限制为模式列表中的相应值。

作为附带说明,请允许我借此机会建议您始终在从两个或多个表读取的查询中使用表别名来限定列。这使您的查询更易于阅读/理解。您始终可以使用短别名,以避免重复可能很长的表名。例如:

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
  ...

6

您应该使用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;

看看MS-Docs上的OR(Transact-SQL)

我建立了一个例子:

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
employee_id | 员工姓名  
:---------- | :--------------
emp10 | 布莱恩·尼尔森(Bryan Nelson)   
emp12 | 罗莎琳·桑德斯(Rosalyn Sanders)
emp13 | 罗斯·图德勒    
emp30 | 伊恩·麦格雷戈   

请记住,无论使用多少条件,您都将使用TOP 1。

SELECT TOP 1 employee_id, employee_name
FROM   employees
WHERE  employee_id LIKE 'emp1%'
OR     employee_id LIKE 'emp3%';
GO
employee_id | 员工姓名
:---------- | :------------
emp10 | 布莱恩·尼尔森(Bryan Nelson)

如果您需要TOP(X)行WHERE employee_id LIKE 'emp1%'加上TOP(X)行WHERE employee_id LIKE 'emp3%',则可以使用两个与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
employee_id | 员工姓名  
:---------- | :--------------
emp10 | 布莱恩·尼尔森(Bryan Nelson)   
emp12 | 罗莎琳·桑德斯(Rosalyn Sanders)
emp13 | 罗斯·图德勒    
emp30 | 伊恩·麦格雷戈   

另外,我将添加模式搜索,但是此解决方案将返回与模式匹配的所有记录:LIKE'emp [13]%'

SELECT employee_id, employee_name
FROM   employees
WHERE  employee_id LIKE 'emp[13]%'
GO
employee_id | 员工姓名  
:---------- | :--------------
emp10 | 布莱恩·尼尔森(Bryan Nelson)   
emp12 | 罗莎琳·桑德斯(Rosalyn Sanders)
emp13 | 罗斯·图德勒    
emp30 | 伊恩·麦格雷戈   

dbfiddle 在这里


2

我想你想要一排where employee_id like 'emp1%'又一排where employee_id like 'emp3%'。实现此目的的一种方法是使用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 ;

由于可以保证联合中的支脚不相交,UNION ALL因此可以使用a,与仅使用a相比,这可能是性能优势UNION

我相信SQL Server 2008支持诸如row_number()之类的窗口函数,因此您可以使用类似以下内容的方法:

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;

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.