2009-09-07 11 views
54

Chcę napisać instrukcję SQL jak poniżej:W jaki sposób można wprowadzić wiele warunków w LIKE operatora

select * from tbl where col like ('ABC%','XYZ%','PQR%'); 

wiem, można to zrobić za pomocą OR. Ale chcę wiedzieć, czy istnieje lepsze rozwiązanie.

+1

Co jest nie tak z OR? Czy masz dynamiczny zestaw warunków? –

+0

Co jest nie tak z OR? Ilość pisania? –

+1

Oczywiście użyłem OR w czasie rzeczywistym. Ale chcę wiedzieć, czy istnieje inny sposób na zastąpienie OR – Madhu

Odpowiedz

35

Oto alternatywny sposób:

select * from tbl where col like 'ABC%' 
union 
select * from tbl where col like 'XYZ%' 
union 
select * from tbl where col like 'PQR%'; 

Oto kod testu w celu sprawdzenia:

create table tbl (col varchar(255)); 
insert into tbl (col) values ('ABCDEFG'), ('HIJKLMNO'), ('PQRSTUVW'), ('XYZ'); 
select * from tbl where col like 'ABC%' 
union 
select * from tbl where col like 'XYZ%' 
union 
select * from tbl where col like 'PQR%'; 
+----------+ 
| col  | 
+----------+ 
| ABCDEFG | 
| XYZ  | 
| PQRSTUVW | 
+----------+ 
3 rows in set (0.00 sec) 
57

To jest dobre wykorzystanie tabeli tymczasowej.

CREATE TEMPORARY TABLE patterns (
    pattern VARCHAR(20) 
); 

INSERT INTO patterns VALUES ('ABC%'), ('XYZ%'), ('PQR%'); 

SELECT t.* FROM tbl t JOIN patterns p ON (t.col LIKE p.pattern); 

W przykładowych wzorów, nie ma mowy col mógł dopasować więcej niż jeden wzór, dzięki czemu można mieć pewność, zobaczysz każdy wiersz tbl co najwyżej raz w wyniku. Ale jeśli twoje wzorce są takie, że col mogą pasować do więcej niż jednego, powinieneś użyć modyfikatora zapytania DISTINCT.

SELECT DISTINCT t.* FROM tbl t JOIN patterns p ON (t.col LIKE p.pattern); 
+0

To nie zadziała dla użytkowników PostgreSQL. – LittleBobbyTables

4

To może pomóc:

select * from tbl where col like '[ABC-XYZ-PQR]%' 

Używałem tego w SQL Server 2005 i to działało.

+6

Czy nie daje to nieistotnego wyniku? – NileshChauhan

+0

Jest to idealne rozwiązanie do wyciągania częściowo pasujących kodów z zestawów danych, np. ze znakami dołączonymi do tego samego kodu bazowego, aby określić położenie geograficzne – Hilary

3
select * from tbl where col like 'ABC%' 
or col like 'XYZ%' 
or col like 'PQR%'; 

Działa to w ropuchach i siłowniku. Nie wiem, o reszcie

+2

Właściwie to jest składnia użytego OP; chcieli * alternatywy * do tego sformułowania. – APC

+0

Działa również w oprogramowaniu Oracle SQL. – Shams

35

Oracle 10g zawiera funkcje, które umożliwiają korzystanie z wyrażeń regularnych zgodnych z POSIX w SQL:

  • REGEXP_LIKE
  • REGEXP_REPLACE
  • REGEXP_INSTR
  • REGEXP_SUBSTR

Szczegóły dotyczące składni tej funkcji można znaleźć w dokumencie Oracle Database SQL Reference.

Zobacz przykłady z użyciem Regular expressions in Perl.

Kod:

select * from tbl where regexp_like(col, '^(ABC|XYZ|PQR)'); 
+1

Oracle może oczywiście używać indeksu dla 'LIKE 'ABC%'', ale nie wierzę, że może użyć indeksu dla operacji REGEX (chyba że jest to indeks oparty na funcjonie) – symcbean

2

miałem również ten sam wymóg gdzie nie mają wyboru, aby przekazać jak wiele razy przez operatora albo robi zapytanie lub czy pisanie Unii.

This worked for me in Oracle 11g: 

REGEXP_LIKE (column, 'ABC.*|XYZ.*|PQR.*'); 
0

Nawet u mogą spróbować tej

funkcji

CREATE FUNCTION [dbo].[fn_Split](@text varchar(8000), @delimiter varchar(20)) 
RETURNS @Strings TABLE 
( 
    position int IDENTITY PRIMARY KEY, 
    value varchar(8000) 
) 
AS 
BEGIN 

DECLARE @index int 
SET @index = -1 

WHILE (LEN(@text) > 0) 
    BEGIN 
    SET @index = CHARINDEX(@delimiter , @text) 
    IF (@index = 0) AND (LEN(@text) > 0) 
     BEGIN 
     INSERT INTO @Strings VALUES (@text) 
      BREAK 
     END 
    IF (@index > 1) 
     BEGIN 
     INSERT INTO @Strings VALUES (LEFT(@text, @index - 1)) 
     SET @text = RIGHT(@text, (LEN(@text) - @index)) 
     END 
    ELSE 
     SET @text = RIGHT(@text, (LEN(@text) - @index)) 
    END 
    RETURN 
END 

Zapytanie

select * from my_table inner join (select value from fn_split('ABC,MOP',',')) 
as split_table on my_table.column_name like '%'+split_table.value+'%'; 
0

Jeśli wartość parametru nie jest ustalona lub swoją wartość może być zerowy na podstawie działalności gospodarczej można spróbuj zastosować następujące podejście.

DECLARE @DrugClassstring VARCHAR(MAX); 
SET @DrugClassstring = 'C3,C2'; -- You can pass null also 

--------------------------------------------- 

IF @DrugClassstring IS NULL 
    SET @DrugClassstring = 'C3,C2,C4,C5,RX,OT'; -- If null you can set your all conditional case that will return for all 
SELECT dn.drugclass_FK , dn.cdrugname 
FROM drugname AS dn 
INNER JOIN dbo.SplitString(@DrugClassstring, ',') class ON dn.drugclass_FK = class.[Name] -- SplitString is a a function 

funkcja SplitString

SET ANSI_NULLS ON; 
GO 
SET QUOTED_IDENTIFIER ON; 
GO 
ALTER FUNCTION [dbo].[SplitString](@stringToSplit VARCHAR(MAX), 
            @delimeter  CHAR(1)  = ',') 
RETURNS @returnList TABLE([Name] [NVARCHAR](500)) 
AS 
    BEGIN 

     --It's use in report sql, before any change concern to everyone 

     DECLARE @name NVARCHAR(255); 
     DECLARE @pos INT; 
     WHILE CHARINDEX(@delimeter, @stringToSplit) > 0 
      BEGIN 
       SELECT @pos = CHARINDEX(@delimeter, @stringToSplit); 
       SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1); 
       INSERT INTO @returnList 
         SELECT @name; 
       SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)[email protected]); 
      END; 
     INSERT INTO @returnList 
       SELECT @stringToSplit; 
     RETURN; 
    END; 
0

SELECT * Z tbl GDZIE kol JAK '[0-9, A-Z]%';

po prostu użyj tego warunku jak w sql, a dostaniesz żądaną odpowiedź

Powiązane problemy