เป็นไปได้ไหมที่จะใช้ประโยคIFภายในWHERE clause ใน MS SQL?
ตัวอย่าง:
WHERE
IF IsNumeric(@OrderNumber) = 1
OrderNumber = @OrderNumber
ELSE
OrderNumber LIKE '%' + @OrderNumber + '%'
เป็นไปได้ไหมที่จะใช้ประโยคIFภายในWHERE clause ใน MS SQL?
ตัวอย่าง:
WHERE
IF IsNumeric(@OrderNumber) = 1
OrderNumber = @OrderNumber
ELSE
OrderNumber LIKE '%' + @OrderNumber + '%'
คำตอบ:
ใช้คำสั่งCASE
UPDATE:ไวยากรณ์ก่อนหน้า (ตามที่อธิบายโดยบางคน) ไม่ทำงาน คุณสามารถใช้ CASE ได้ดังต่อไปนี้:
WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber) = 1 THEN
@OrderNumber
ELSE
'%' + @OrderNumber
END
หรือคุณสามารถใช้คำสั่ง IF เช่น @ NJ Reedชี้ให้เห็น
CASE
เป็นวิธีแก้ปัญหาที่เหมาะสมในกรณีส่วนใหญ่ ในกรณีของฉันฉันต้องการเปลี่ยนแปลงตัวดำเนินการเปรียบเทียบและด้วยเหตุนี้ฉันจึงใช้วิธีการถัดไป
คุณควรจะสามารถทำได้โดยไม่มี IF หรือ CASE
WHERE
(IsNumeric(@OrderNumber) AND
(CAST OrderNumber AS VARCHAR) = (CAST @OrderNumber AS VARCHAR)
OR
(NOT IsNumeric(@OrderNumber) AND
OrderNumber LIKE ('%' + @OrderNumber))
ทั้งนี้ขึ้นอยู่กับรสชาติของ SQL คุณอาจต้องปรับแต่ง casts ตามหมายเลขคำสั่งไปที่ INT หรือ VARCHAR ทั้งนี้ขึ้นอยู่กับว่ารองรับ casts โดยปริยายหรือไม่
นี่เป็นเทคนิคที่พบบ่อยมากใน WHERE clause หากคุณต้องการใช้ตรรกะ "IF" บางอย่างใน WHERE clause ทั้งหมดที่คุณต้องทำคือการเพิ่มเงื่อนไขพิเศษด้วยบูลีนและในส่วนที่จำเป็นต้องใช้
คุณไม่จำเป็นต้องมีคำสั่ง IF เลย
WHERE
(IsNumeric(@OrderNumber) = 1 AND OrderNumber = @OrderNumber)
OR (IsNumeric(@OrderNumber) = 0 AND OrderNumber LIKE '%' + @OrderNumber + '%')
where (@AdmUserId is null or CurrentOrder.CustomerAdmUserId = @AdmUserId)
หรือกรองเฉพาะถ้า IncludeDeleted = 0: where (@IncludeDeleted = 1 or ItemObject.DeletedFlag = 0)
ไม่มีวิธีที่ดีในการทำเช่นนี้ใน 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) ใช้ 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
วิธีที่ 3 นั้นน่ากลัว แต่เกือบจะเป็นความคิดเดียวที่ใช้ได้ผลถ้าคุณมีเงื่อนไขหลายอย่างเช่นนั้น
IF...ELSE...
เงื่อนไขทั้งหมดของคุณเป็นบูลีนAND
และOR
ใน @ njr101 คำตอบข้างต้น ข้อเสียของ ^ วิธีนี้คือมันอาจเป็นเรื่องยากหากสมองของคุณมีหลายคนIF
หรือถ้าคุณมีหลายอย่างที่ซ้อนกัน
ใช้คำสั่งCASEแทน IF
คุณต้องการคำสั่ง CASE
WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber)=1 THEN @OrderNumber ELSE '%' + @OrderNumber END
ฉันคิดว่าที่ ... เช่น / = ... กรณี ... จากนั้น ... สามารถทำงานกับ Booleans ฉันใช้ T-SQL
สถานการณ์สมมติ: สมมติว่าคุณต้องการรับงานอดิเรกของ 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;
WHERE (IsNumeric (@OrderNumber) <> 1 หรือ OrderNumber = @OrderNumber) AND (IsNumber (@OrderNumber) = 1 หรือหมายเลขคำสั่งซื้อเช่น '%' + @OrderNumber + '%')
IF P THEN Q ELSE R
<=>
( ( NOT P ) OR Q ) AND ( P OR R )
คำชี้แจงกรณีเป็นตัวเลือกที่ดีกว่าถ้าเสมอ
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
ในกรณีบรรทัดสภาพจะทำงานอย่างถูกต้อง
ตัวอย่างต่อไปนี้เรียกใช้คิวรีเป็นส่วนหนึ่งของนิพจน์บูลีนจากนั้นเรียกใช้บล็อกคำสั่งที่แตกต่างกันเล็กน้อยโดยยึดตามผลลัพธ์ของนิพจน์บูลีน แต่ละบล็อกคำสั่งเริ่มต้นด้วย 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 ... ซ้อนกันตัวอย่างต่อไปนี้แสดงให้เห็นว่าคำสั่ง 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
ในเซิร์ฟเวอร์ sql ฉันมีปัญหาเดียวกันฉันต้องการใช้และคำสั่งเฉพาะถ้าพารามิเตอร์เป็นเท็จและจริงฉันต้องแสดงทั้งค่าจริงและเท็จดังนั้นฉันจึงใช้วิธีนี้
(T.IsPublic = @ShowPublic or @ShowPublic = 1)
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