programing

SQL: WHERE 절 내의 IF 절

bestprogram 2023. 4. 7. 22:04

SQL: WHERE 절 내의 IF 절

MS SQL의 WHERE 절 에 IF 절을 사용할 수 있습니까?

예:

WHERE
    IF IsNumeric(@OrderNumber) = 1
        OrderNumber = @OrderNumber
    ELSE
        OrderNumber LIKE '%' + @OrderNumber + '%'

CASE 스테이트먼트 사용
업데이트: 이전 구문(몇 명이 지적한 대로)이 작동하지 않습니다.CASE는 다음과 같이 사용할 수 있습니다.

WHERE OrderNumber LIKE
  CASE WHEN IsNumeric(@OrderNumber) = 1 THEN 
    @OrderNumber 
  ELSE
    '%' + @OrderNumber
  END

또는 @N. J. Reed가 지적하는 것과 같은 IF 문을 사용할 수 있습니다.

IF나 CASE 없이 이 작업을 수행할 수 있어야 합니다.

 WHERE 
   (IsNumeric(@OrderNumber) AND
      (CAST OrderNumber AS VARCHAR) = (CAST @OrderNumber AS VARCHAR)
 OR
   (NOT IsNumeric(@OrderNumber) AND
       OrderNumber LIKE ('%' + @OrderNumber))

SQL의 맛에 따라서는 주문 번호의 캐스트를 INT 또는 VARCHAR로 조정해야 할 수도 있습니다.

이것은 WHERE 절에서 매우 일반적인 기술입니다.WHERE 절에 "IF" 로직을 적용할 경우 필요한 섹션에 부울 AND를 사용하여 추가 조건을 추가하면 됩니다.

IF 문장은 전혀 필요 없습니다.

WHERE
    (IsNumeric(@OrderNumber) = 1 AND OrderNumber = @OrderNumber)
OR (IsNumeric(@OrderNumber) = 0 AND OrderNumber LIKE '%' + @OrderNumber + '%')

SQL에서는 이 작업을 수행하는 데 좋은 방법이 없습니다.지금까지 본 몇 가지 접근법:

1) CASE를 부울 연산자와 조합하여 사용한다:

WHERE
    OrderNumber = CASE 
        WHEN (IsNumeric(@OrderNumber) = 1)
        THEN CONVERT(INT, @OrderNumber)
        ELSE -9999 -- Some numeric value that just cannot exist in the column
    END
    OR 
    FirstName LIKE CASE
        WHEN (IsNumeric(@OrderNumber) = 0)
        THEN '%' + @OrderNumber
        ELSE ''
    END

2) SELECT 이외의 IF를 사용한다.

IF (IsNumeric(@OrderNumber)) = 1
BEGIN
    SELECT * FROM Table
    WHERE @OrderNumber = OrderNumber
END ELSE BEGIN
    SELECT * FROM Table
    WHERE OrderNumber LIKE '%' + @OrderNumber
END

3) 긴 문자열을 사용하여 조건부로 SQL 문을 작성한 후 EXEC을 사용합니다.

세 번째 접근법은 끔찍하지만, 그런 가변적인 조건들을 가지고 있다면 거의 유일하게 효과가 있다고 생각합니다.

IF 대신 CASE 을 사용합니다.

논리적 동등성 솔루션의 일부를 명확히 한다.

if 스테이트먼트

if (a) then b

논리적으로 와 동등하다

(!a || b)

논리적 동등성 위키피디아 문서의 조건문을 포함하는 논리적 동등성 섹션의 첫 번째 줄입니다.

다른 것을 포함하려면 다른 조건을 추가하기만 하면 됩니다.

if(a) then b; 
if(!a) then c;

논리적으로 (!a | | b) & (a | | c)에 상당합니다.

OP를 예로 들어 보겠습니다.

IF IsNumeric(@OrderNumber) = 1
    OrderNumber = @OrderNumber
ELSE
    OrderNumber LIKE '%' + @OrderNumber + '%'

논리적으로 동등한 것은 다음과 같습니다.

(IsNumeric(@OrderNumber) <> 1 OR OrderNumber = @OrderNumber)
AND (IsNumeric(@OrderNumber) = 1 OR OrderNumber LIKE '%' + @OrderNumber + '%' )

CASE 스테이트먼트가 필요한 경우

WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber)=1 THEN @OrderNumber ELSE '%' + @OrderNumber END

제 생각에는... 예를 들면... = 케이스... 그럼...Bohans와 함께 일할 수 있습니다.T-SQL을 사용하고 있습니다.

시나리오:만약 Bool이 거짓이라면 Person-30의 취미를 얻고자 한다면 Person-42의 취미를 얻고자 한다면요.(일부에 따르면 취미 검색은 비즈니스 계산 주기의 90% 이상을 차지하기 때문에 가까운 금액을 지불해야 한다.)

CREATE PROCEDURE sp_Case
@bool   bit
AS
SELECT Person.Hobbies
FROM Person
WHERE Person.ID = 
    case @bool 
        when 0 
            then 30
        when 1
            then 42
    end;

// 저장 프로시저를 사용하여 국가 및 사이트별로 필터링된 사용자를 선택하는 예

CREATE STORED PROCEDURE GetUsers
@CountryId int = null,
@SiteId int = null
AS
BEGIN
SELECT *
        FROM Users
        WHERE
                CountryId  = CASE WHEN ISNUMERIC(@CountryId) = 1 THEN @CountryId ELSE CountryId END AND 
                SiteId     = CASE WHEN ISNUMERIC(@SiteId) = 1 THEN @SiteId ELSE SiteId END END

// 입력 countryId AND/OR siteId(존재하는 경우)에서 가져오고 그렇지 않으면 필터링하지 않습니다.

WHERE(IsNumeric(@OrderNumber) <> 1 OR OrderNumber = @OrderNumber)AND(IsNumber(@OrderNumber) = 1 OR OrderNumber Like '%'+ @OrderNumber + '%'

CASE Statement는 항상 IF보다 좋은 옵션입니다.

  WHERE  vfl.CreatedDate >= CASE WHEN @FromDate IS NULL THEN vfl.CreatedDate ELSE  @FromDate END
    AND vfl.CreatedDate<=CASE WHEN @ToDate IS NULL THEN vfl.CreatedDate ELSE @ToDate END 
    WHERE OrderNumber LIKE CASE WHEN IsNumeric(@OrderNumber) = 1 THEN @OrderNumber ELSE  '%' + @OrderNumber END

라인 케이스에서는 컨디션이 정상적으로 동작합니다.

sql 서버에서도 파라미터가 false일 경우에만및 문을 사용하고 싶었고 true일 경우 true와 false 값을 모두 표시해야 했기 때문에 이렇게 사용했습니다.

(T.IsPublic = @ShowPublic or  @ShowPublic = 1)

다음 예제에서는 부울식의 일부로 쿼리를 실행하고 부울식의 결과에 따라 약간 다른 스테이트먼트블록을 실행합니다.각 문 블록은 BEGIN으로 시작하여 END로 완료됩니다.

USE AdventureWorks2012;
GO
DECLARE @AvgWeight decimal(8,2), @BikeCount int
IF 
(SELECT COUNT(*) FROM Production.Product WHERE Name LIKE 'Touring-3000%' ) > 5
BEGIN
   SET @BikeCount = 
        (SELECT COUNT(*) 
         FROM Production.Product 
         WHERE Name LIKE 'Touring-3000%');
   SET @AvgWeight = 
        (SELECT AVG(Weight) 
         FROM Production.Product 
         WHERE Name LIKE 'Touring-3000%');
   PRINT 'There are ' + CAST(@BikeCount AS varchar(3)) + ' Touring-3000 bikes.'
   PRINT 'The average weight of the top 5 Touring-3000 bikes is ' + CAST(@AvgWeight AS varchar(8)) + '.';
END
ELSE 
BEGIN
SET @AvgWeight = 
        (SELECT AVG(Weight)
         FROM Production.Product 
         WHERE Name LIKE 'Touring-3000%' );
   PRINT 'Average weight of the Touring-3000 bikes is ' + CAST(@AvgWeight AS varchar(8)) + '.' ;
END ;
GO

중첩된 IF 사용 중...ELSE 스테이트먼트 다음 예시는 IF … ELSE 스테이트먼트를 다른 스테이트먼트 내에 네스트 하는 방법을 나타내고 있습니다.각 문을 테스트하려면 @Number 변수를 5, 50 및 500으로 설정합니다.

DECLARE @Number int
SET @Number = 50
IF @Number > 100
   PRINT 'The number is large.'
ELSE 
   BEGIN
      IF @Number < 10
      PRINT 'The number is small'
   ELSE
      PRINT 'The number is medium'
   END ;
GO
If @LstTransDt is Null
                begin
                    Set @OpenQty=0
                end
            else
                begin
                   Select   @OpenQty=IsNull(Sum(ClosingQty),0)  
                   From  ProductAndDepotWiseMonitoring  
                   Where   Pcd=@PCd And PtpCd=@PTpCd And TransDt=@LstTransDt      
                end 

이게 도움이 되는지 보세요.

USE AdventureWorks2012;
GO
IF 
(SELECT COUNT(*) FROM Production.Product WHERE Name LIKE 'Touring-3000%' ) > 5
PRINT 'There are more than 5 Touring-3000 bicycles.'
ELSE PRINT 'There are 5 or less Touring-3000 bicycles.' ;
GO

언급URL : https://stackoverflow.com/questions/87821/sql-if-clause-within-where-clause