SQL تبديل / حالة في البند 'حيث'
-
03-07-2019 - |
سؤال
وحاولت البحث حولها، ولكن لم أجد أي شيء من شأنه مساعدتي.
وأنا أحاول القيام بذلك في SQL:
declare @locationType varchar(50);
declare @locationID int;
SELECT column1, column2
FROM viewWhatever
WHERE
CASE @locationType
WHEN 'location' THEN account_location = @locationID
WHEN 'area' THEN xxx_location_area = @locationID
WHEN 'division' THEN xxx_location_division = @locationID
وأنا أعلم أنني لا ينبغي أن يضع '=locationID' في نهاية كل واحدة، ولكن لا أستطيع الحصول على بناء الجملة حتى على مقربة من كونها صحيحة. SQL يحتفظ تشكو لي '=' في الأول عندما خط ...
وكيف يمكنني أن أفعل هذا؟
المحلول
declare @locationType varchar(50);
declare @locationID int;
SELECT column1, column2
FROM viewWhatever
WHERE
@locationID =
CASE @locationType
WHEN 'location' THEN account_location
WHEN 'area' THEN xxx_location_area
WHEN 'division' THEN xxx_location_division
END
نصائح أخرى
ودون بيان حالة ...
SELECT column1, column2
FROM viewWhatever
WHERE
(@locationType = 'location' AND account_location = @locationID)
OR
(@locationType = 'area' AND xxx_location_area = @locationID)
OR
(@locationType = 'division' AND xxx_location_division = @locationID)
وهنا تذهب.
SELECT
column1,
column2
FROM
viewWhatever
WHERE
CASE
WHEN @locationType = 'location' AND account_location = @locationID THEN 1
WHEN @locationType = 'area' AND xxx_location_area = @locationID THEN 1
WHEN @locationType = 'division' AND xxx_location_division = @locationID THEN 1
ELSE 0
END = 1
وانا اقول هذا هو مؤشر على بنية الجدول معيبة. ربما يجب فصل أنواع مختلفة موقع في جداول مختلفة، مما يتيح لك أن تفعل الاستعلام عن أكثر ثراء بكثير، وأيضا تجنب الأعمدة زائدة حولها.
إذا كنت غير قادر على تغيير هيكل، شيء من هذا القبيل أدناه قد عمل:
SELECT
*
FROM
Test
WHERE
Account_Location = (
CASE LocationType
WHEN 'location' THEN @locationID
ELSE Account_Location
END
)
AND
Account_Location_Area = (
CASE LocationType
WHEN 'area' THEN @locationID
ELSE Account_Location_Area
END
)
وهكذا دواليك ... نحن لا نستطيع تغيير هيكل الاستعلام على الطاير، ولكن يمكننا تجاوز ذلك من خلال جعل المسندات تساوي أنفسهم.
وتحرير: والاقتراحات المذكورة أعلاه هي بطبيعة الحال أفضل بكثير، فقط تجاهل الألغام
.والمشكلة مع هذا هي أنه عندما يذهب محرك SQL لتقييم التعبير، فإنه يتحقق من جزء لسحب الجداول المناسبة، ومن ثم WHERE جزء لتوفير بعض المعايير الأساسية، لذلك لا يمكن تقييم صحيح شرط الحيوية على العمود الذي للتحقق ضده.
ويمكنك استخدام جملة WHERE عندما كنت التحقق من معايير WHERE في المسند، مثل
WHERE account_location = CASE @locationType
WHEN 'business' THEN 45
WHEN 'area' THEN 52
END
وذلك في حالة معينة، وأنت تسير في حاجة إلى وضع الاستعلام إلى إجراء مخزن أو إنشاء ثلاثة استعلامات منفصلة.
وأو المشغل يمكن أن يكون بديلا للحالة عندما تكون في حالة حيث
ALTER PROCEDURE [dbo].[RPT_340bClinicDrugInventorySummary]
-- Add the parameters for the stored procedure here
@ClinicId BIGINT = 0,
@selecttype int,
@selectedValue varchar (50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT
drugstock_drugname.n_cur_bal,drugname.cdrugname,clinic.cclinicname
FROM drugstock_drugname
INNER JOIN drugname ON drugstock_drugname.drugnameid_FK = drugname.drugnameid_PK
INNER JOIN drugstock_drugndc ON drugname.drugnameid_PK = drugstock_drugndc.drugnameid_FK
INNER JOIN drugndc ON drugstock_drugndc.drugndcid_FK = drugndc.drugid_PK
LEFT JOIN clinic ON drugstock_drugname.clinicid_FK = clinic.clinicid_PK
WHERE (@ClinicId = 0 AND 1 = 1)
OR (@ClinicId != 0 AND drugstock_drugname.clinicid_FK = @ClinicId)
-- Alternative Case When You can use OR
AND ((@selecttype = 1 AND 1 = 1)
OR (@selecttype = 2 AND drugname.drugnameid_PK = @selectedValue)
OR (@selecttype = 3 AND drugndc.drugid_PK = @selectedValue)
OR (@selecttype = 4 AND drugname.cdrugclass = 'C2')
OR (@selecttype = 5 AND LEFT(drugname.cdrugclass, 1) = 'C'))
ORDER BY clinic.cclinicname, drugname.cdrugname
END
يرجى محاولة هذا الاستعلام. الإجابة لآخر أعلاه:
select @msgID, account_id
from viewMailAccountsHeirachy
where
CASE @smartLocationType
WHEN 'store' THEN account_location
WHEN 'area' THEN xxx_location_area
WHEN 'division' THEN xxx_location_division
WHEN 'company' THEN xxx_location_company
END = @smartLocation
وجرب هذا:
WHERE (
@smartLocationType IS NULL
OR account_location = (
CASE
WHEN @smartLocationType IS NOT NULL
THEN @smartLocationType
ELSE account_location
END
)
)
Case Statement in SQL Server Example
Syntax
CASE [ expression ]
WHEN condition_1 THEN result_1
WHEN condition_2 THEN result_2
...
WHEN condition_n THEN result_n
ELSE result
END
Example
SELECT contact_id,
CASE website_id
WHEN 1 THEN 'TechOnTheNet.com'
WHEN 2 THEN 'CheckYourMath.com'
ELSE 'BigActivities.com'
END
FROM contacts;
OR
SELECT contact_id,
CASE
WHEN website_id = 1 THEN 'TechOnTheNet.com'
WHEN website_id = 2 THEN 'CheckYourMath.com'
ELSE 'BigActivities.com'
END
FROM contacts;
وحاول هذا الاستعلام. من السهل جدا أن نفهم:
CREATE TABLE PersonsDetail(FirstName nvarchar(20), LastName nvarchar(20), GenderID int);
GO
INSERT INTO PersonsDetail VALUES(N'Gourav', N'Bhatia', 2),
(N'Ramesh', N'Kumar', 1),
(N'Ram', N'Lal', 2),
(N'Sunil', N'Kumar', 3),
(N'Sunny', N'Sehgal', 1),
(N'Malkeet', N'Shaoul', 3),
(N'Jassy', N'Sohal', 2);
GO
SELECT FirstName, LastName, Gender =
CASE GenderID
WHEN 1 THEN 'Male'
WHEN 2 THEN 'Female'
ELSE 'Unknown'
END
FROM PersonsDetail