it-swarm.asia

حدد قيم متعددة في LIKE Operator

لدي استعلام 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؟

10
l.lijith

بدلاً من ذلك ، يمكنك تجربة الطريقة التالية:

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
  ...
16
Andriy M

يجب عليك استخدام شرط 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;

ألق نظرة على OR (Transact-SQL) على MS-Docs.

لقد قمت بإعداد مثال:

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
 worker_id | اسم_الموظف 
: ------- : -------------- 
 emp10 | بريان نيلسون 
 emp12 | روزالين ساندرز 
 emp13 | روز تودلر 
 emp30 | إيان مكجريجور 

ضع في اعتبارك أنك تستخدم TOP 1 ، ستحصل على صف واحد كحد أقصى ، بغض النظر عن عدد الشروط التي تستخدمها.

SELECT TOP 1 employee_id, employee_name
FROM   employees
WHERE  employee_id LIKE 'emp1%'
OR     employee_id LIKE 'emp3%';
GO
 worker_id | اسم_الموظف 
: ---------- | : ------------ 
 emp10 | بريان نيلسون 

إذا كنت بحاجة إلى الصفوف العليا (X) WHERE employee_id LIKE 'emp1%' بالإضافة إلى صفوف (X) TOP 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
 worker_id | اسم_الموظف 
: ---------- | : -------------- 
 emp10 | بريان نيلسون 
 emp12 | روزالين ساندرز 
 emp13 | روز تودلر 
 emp30 | إيان مكجريجور 

بالإضافة إلى ذلك ، سأضيف بحثًا عن الأنماط ، لكن هذا الحل يُرجع كافة السجلات التي تطابق النمط: LIKE 'emp [13]٪'

SELECT employee_id, employee_name
FROM   employees
WHERE  employee_id LIKE 'emp[13]%'
GO
 worker_id | اسم_الموظف 
: ---------- | : -------------- 
 emp10 | بريان نيلسون 
 emp12 | روزالين ساندرز 
 emp13 | روز تودلر 
 emp30 | إيان مكجريجور 

dbfiddle --- (هنا

6
McNets

أعتقد أنك تريد صفًا واحدًا 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 ، وقد يكون ذلك ميزة أداء مقارنة باستخدام 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;
2
Lennart