Wie kann ich mehrere Bedingungen in den LIKE-Operator einführen?

73

Ich möchte eine SQL-Anweisung wie folgt schreiben:

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

Ich weiß, dass es mit gemacht werden kann OR . Aber ich möchte wissen, ob es eine bessere Lösung gibt.

Madhu
quelle
2
Was ist los mit OR? Oder haben Sie dynamische Bedingungen?
Tomas Aschan
Was ist los mit OPs? Die Lautstärke der Eingabe?
Matthew Lock
1
Offensichtlich habe ich OR in Echtzeit verwendet. Aber ich möchte wissen, ob es einen anderen Weg gibt, OR zu ersetzen
Madhu
Es gibt andere Wege als OR'ing der LIKE-Prädikate zusammen, aber es gibt keinen besseren Weg.
Jeffrey Kemp
2
UNION zu machen ist nur Zeitverschwendung, wenn die SELECT-Abfrage groß ist. ODER ist der beste Weg und würde ausreichen, um den Zweck der gestellten Frage zu unterstützen. Vielen Dank.
Könige

Antworten:

45

Hier ist ein alternativer Weg:

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

Hier ist der zu überprüfende Testcode:

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)
Asaph
quelle
61

Dies ist eine gute Verwendung einer temporären Tabelle.

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);

In den Beispielmustern kann nicht colmehr als ein Muster übereinstimmen, sodass Sie sicher sein können, dass jede Zeile tblhöchstens einmal im Ergebnis angezeigt wird. Wenn Ihre Muster jedoch so sind, dass colsie mit mehreren übereinstimmen können, sollten Sie den DISTINCTAbfragemodifikator verwenden.

SELECT DISTINCT t.* FROM tbl t JOIN patterns p ON (t.col LIKE p.pattern);
Bill Karwin
quelle
Ausgezeichnet. Genau das, was ich brauchte, um fest codierte Werte aus meinem Code zu entfernen. Meine String-Masken werden in einer Konfigurationstabelle gespeichert. Der alte Code war jeweils fest codiert. Dies war keine elegante Lösung zum Ändern von Werten und würde Änderungssteuerungsprotokolle erfordern, wenn ich neue Werte hätte. Ich wusste nicht, dass Sie die Syntax "ON (my_field LIKE my_mask)" verwenden können. Danke.
Shari W
Ja! Sie können einen beliebigen Ausdruck als Verknüpfungsbedingung verwenden. Die meisten Menschen verwenden einen einfachen Gleichheitsvergleich, aber das ist keine Einschränkung.
Bill Karwin
46

Oracle 10g verfügt über Funktionen, die die Verwendung von POSIX-kompatiblen regulären Ausdrücken in SQL ermöglichen:

  • REGEXP_LIKE
  • REGEXP_REPLACE
  • REGEXP_INSTR
  • REGEXP_SUBSTR

Siehe die Oracle Database SQL-Referenz Informationen zur Syntax dieser Funktionen finden .

Schauen Sie sich reguläre Ausdrücke in Perl an mit Beispielen an.

Code:

    select * from tbl where regexp_like(col, '^(ABC|XYZ|PQR)');
stefannebesnak
quelle
1
Oracle kann sicherlich einen Index für verwenden, LIKE 'ABC%'aber ich glaube nicht, dass es einen Index für REGEX-Operationen verwenden kann (es sei denn, es ist ein funktionsbasierter Index)
symcbean
Dies ist der beste Ansatz ... Vielen Dank für das Teilen. Es war wirklich hilfreich, obwohl es ein alter Beitrag war.
NIK
8
select * from tbl where col like 'ABC%'
or col like 'XYZ%'
or col like 'PQR%';

Dies funktioniert in Kröte und Powerbuilder. Ich weiß nichts über den Rest

KathMania
quelle
3
Eigentlich ist das die Syntax, die das OP verwendet; Sie wollten Alternativen zu dieser Formulierung.
APC
Funktioniert auch in Oracle SQL-Entwicklern.
Shams
6

Dies könnte helfen:

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

Ich habe dies in SQL Server 2005 verwendet und es hat funktioniert.

Eric
quelle
6
Gibt es kein irrelevantes Ergebnis?
NileshChauhan
Dies ist perfekt, um teilweise übereinstimmende Codes aus Datensätzen zu ziehen, z. B. mit Zeichen, die an denselben Basiscode angehängt sind, um den geografischen Standort zu kennzeichnen
Hilary
Es gibt keine erforderlichen Aufzeichnungen
Rajesh Om
2

Ich hatte auch die gleiche Anforderung, bei der ich nicht die Wahl hatte, mehrmals wie ein Operator zu übergeben, indem ich entweder ein ODER durchführte oder eine Gewerkschaftsabfrage schrieb.

This worked for me in Oracle 11g:

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

Sogar du kannst es versuchen

Funktion

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

Abfrage

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+'%';
SimarjeetSingh Panghlia
quelle
0

Wenn Ihr Parameterwert nicht festgelegt ist oder Ihr Wert geschäftlich null sein kann, können Sie den folgenden Ansatz ausprobieren.

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

SplitString-Funktion

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)-@pos);
             END;
         INSERT INTO @returnList
                SELECT @stringToSplit;
         RETURN;
     END;
Atik Sarker
quelle
0

SELECT * From tbl WHERE col LIKE '[0-9, az]%';

Verwenden Sie einfach diese Bedingung wie in SQL und Sie erhalten Ihre gewünschte Antwort

Harry Sandale
quelle