Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“where”子句中的SQL开关/大小写_Sql_Switch Statement_Case - Fatal编程技术网

“where”子句中的SQL开关/大小写

“where”子句中的SQL开关/大小写,sql,switch-statement,case,Sql,Switch Statement,Case,我试着四处寻找,但找不到任何能帮我的东西 我尝试在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_locat

我试着四处寻找,但找不到任何能帮我的东西

我尝试在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
    *
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引擎计算表达式时,它会检查FROM部分以提取适当的表,然后检查WHERE部分以提供一些基本条件,因此,它无法正确评估要检查的列的动态条件

在检查谓词中的WHERE条件时,可以使用WHERE子句,例如

WHERE account_location = CASE @locationType
                              WHEN 'business' THEN 45
                              WHEN 'area' THEN 52
                         END
因此,在您的特定情况下,您需要将查询放入存储过程或创建三个单独的查询。

给您

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

尝试此查询。这很容易理解:

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

当处于where条件时,OR运算符可以作为情况的替代

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

试试这个查询,它非常简单而且有用:它已经准备好执行了

USE tempdb
GO

IF NOT OBJECT_ID('Tempdb..Contacts') IS NULL
    DROP TABLE Contacts

CREATE TABLE Contacts(ID INT, FirstName VARCHAR(100), LastName VARCHAR(100))
INSERT INTO Contacts (ID, FirstName, LastName)
SELECT 1, 'Omid', 'Karami'
UNION ALL
SELECT 2, 'Alen', 'Fars'
UNION ALL
SELECT 3, 'Sharon', 'b'
UNION ALL
SELECT 4, 'Poja', 'Kar'
UNION ALL
SELECT 5, 'Ryan', 'Lasr'
GO
 
DECLARE @FirstName VARCHAR(100)
SET @FirstName = 'Omid'
 
DECLARE @LastName VARCHAR(100)
SET @LastName = '' 
 
SELECT FirstName, LastName
FROM Contacts
WHERE  
    FirstName = CASE
    WHEN LEN(@FirstName) > 0 THEN  @FirstName 
    ELSE FirstName 
    END
AND
    LastName = CASE
    WHEN LEN(@LastName) > 0 THEN  @LastName 
    ELSE LastName
    END
GO
这对我有用

创建表每校准年整数,校准每整数 在每校准年中插入校准值20,1,20,2,20,3,20,4,20,5,20,6,20,7,20,8,20,9,20,10,20,11,20,12, 99,1 , 99,2 , 99,3 , 99,4 , 99,5 , 99,6 , 99,7 , 99,8 , 99,9 , 99,10 , 99,11 , 99,12 4位数的世纪由规则决定,如果年份为50或以上,则世纪为1900,否则为2000

给定两个标记开始和结束周期的6位数周期(如四分之一),返回该范围内的行

-2020年第一季度 在202001和202003之间,如果校准年份>50,则选择*从每校准年份,然后选择1900 ELSE 2000结束+校准年份*100+每校准年份 -一九九九年第四季 在199910年和199912年之间,如果校准年份>50,则选择*FROM PER_CAL,然后选择1900 ELSE 2000 END+CAL_YEAR*100+CALU PER
我不认为这是一个有缺陷的桌子结构。该表是以这种方式设置的,因此具有无限多的父/子关系是自引用。相信我,这是故意的。我不想把我的表结构改成只使用switch语句。TomH在下面对您的回复的评论中指出,您的SQL格式不正确。我在SQLServer2005中测试了我的,效果很好。为什么需要@呢?它们是做什么的?@表示t-sql中的变量,如果没有@,@locationID将被解释为一个列名。好吧,我会把它写成SELECT column1,视图中的第2列无论@locationType='location'和account\u location=@locationID或@locationType='area'和xxx\u location\u area=@locationID或@locationType='division'和xxx\u location\u division=@locationID这都是一个很好的例子,如果你想使用不同类型的where子句,比如在第一个子句上使用int,在第二个子句上使用nvarchar,我更喜欢这个方法代码清晰,非常好。对于Bob Probst,解决方案不起作用。谢天谢地,当满足条件后Case语句退出时,这将给出一个稍微不同的结果,但是OR语法将计算所有possibilities@tember即使SQL是一种过程语言,如果第一个OR为true,则表达式的其余部分也不会得到计算。由于SQL是一种声明性语言,您如何知道DBM将对所有ORs进行求值?诚恳的问题,我不明白。在SQL中,表达式的其余部分是用OR语法计算的。试试这个,它不会让我包含@符号-如果你想测试它,你必须纠正它:declare var varchar5 set var='0'选择2/var,其中var 0或ISNUMERICvar=1。我希望条件退出,因为var等于0,但它会继续检查它是否为数值,事实上,因此,该语句返回一个错误。在我的例子中,该语句对类型的每个值都有一个不同的比较运算符。如果@locationType='location'开始选择column1,则最好还是声明@locationType NVARCHAR50='youchoose',如果@locationType='location'开始选择column1,视图中的第2列无论在何处帐户\u位置=@locationID结束如果@locationType='area'开始选择第1列,第2列
从视图中,无论xxx\u location\u area=@locationID END,如果@locationType='division'开始选择column1,第2列FROM view WHERE xxx_location_division=@locationID ENDTo将来读到这篇文章的人:这与上面@bob prost的公认答案是一样的:否决,因为我不明白如何在给定的字符串之间进行选择,即“location”、“area”,对阅读此答案的人进行“分组”:这与上面@bob prost接受的答案相同:因为这个原因投了反对票。投反对票是因为这个答案与问题无关。问题是如何在WHERE子句上使用CASE,而不是如何在所选列上使用CASE。
CREATE PROCEDURE [dbo].[Temp_Proc_Select_City]
    @StateId INT
AS  
        BEGIN       
            SELECT * FROM tbl_City 
                WHERE 
                @StateID = CASE WHEN ISNULL(@StateId,0) = 0 THEN 0 ELSE StateId END ORDER BY CityName
        END
USE tempdb
GO

IF NOT OBJECT_ID('Tempdb..Contacts') IS NULL
    DROP TABLE Contacts

CREATE TABLE Contacts(ID INT, FirstName VARCHAR(100), LastName VARCHAR(100))
INSERT INTO Contacts (ID, FirstName, LastName)
SELECT 1, 'Omid', 'Karami'
UNION ALL
SELECT 2, 'Alen', 'Fars'
UNION ALL
SELECT 3, 'Sharon', 'b'
UNION ALL
SELECT 4, 'Poja', 'Kar'
UNION ALL
SELECT 5, 'Ryan', 'Lasr'
GO
 
DECLARE @FirstName VARCHAR(100)
SET @FirstName = 'Omid'
 
DECLARE @LastName VARCHAR(100)
SET @LastName = '' 
 
SELECT FirstName, LastName
FROM Contacts
WHERE  
    FirstName = CASE
    WHEN LEN(@FirstName) > 0 THEN  @FirstName 
    ELSE FirstName 
    END
AND
    LastName = CASE
    WHEN LEN(@LastName) > 0 THEN  @LastName 
    ELSE LastName
    END
GO