【问题标题】:case statement in where clause - SQL Server 2008where 子句中的 case 语句 - SQL Server 2008
【发布时间】:2013-12-06 21:16:42
【问题描述】:
SELECT  
   PDADate, T.Merchandizer_ID, T.Merchandizer, Merchandizer_LoginName, 
   STORE_ID, STORE_CODE, STORE_NAME,
   ACCOUNT_ID, ACCOUNT_NAME, Account_Store_Format_Id, Account_Store_Format,
   StoreType_Id, StoreType, T.Listid, T.Listname, 
   T.TimeIn, T.TimeOut, T.PlannedDate, T.Reason, TaskCode, TotalTime 
FROM 
   [dbo].Report_RD_Coverage T 
INNER JOIN 
   #TempLocationH TL ON TL.LocationId=T.Location_Id
WHERE 
   CONVERT(Date, PDADate) Between (@Start_Date) AND Isnull(@End_Date, @CurrentDate)
   AND T.Account_Id IN 
       (SELECT 
            CASE WHEN @Account_Id IS NULL THEN T.Account_Id 
                 ELSE (SELECT * FROM UDF_SplitString(@Account_Id,',')) 
            END
       )    
   AND T.StoreType_Id IN 
       (SELECT 
            CASE WHEN @StoreType_Id IS NULL THEN T.StoreType_Id 
                   ELSE (SELECT * FROM UDF_SplitString(@StoreType_Id,',')) 
            END
       )
  AND T.Store_Id IN
      (SELECT 
           CASE WHEN @Store_Id IS NULL THEN T.Store_Id 
                  ELSE (SELECT * FROM UDF_SplitString(@Store_Id,',')) 
           END
      )

如果@Account_Id@StoreType_Id@Store_Id 为空,则应选择所有ACCOUNT_IDSTORETYPE_IDSTORE_ID,否则应根据参数值进行过滤。

UDF_SplitString是分割逗号分隔字符串的函数,它的返回值是一个像这样的表格:

 - 1
 - 2
 - 3

我收到此错误:

子查询返回超过 1 个值。当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的。

【问题讨论】:

  • 这就是它所说的意思。 IN 语句显然返回不止一行。我会检查每个 IN 语句并验证它返回的行不超过 1 行。
  • 我猜这个人正在这样做:SELECT * FROM UDF_SplitString(@Account_Id,',')) END。指定 UDF_SplitString 函数中返回内容的列名。
  • UDF_SplitString 是逗号分隔符的功能,它正在返回 table 中的值。喜欢
  • 嗨,伙计,我得到了答案..

标签: sql-server-2008 runtime-error case where-in


【解决方案1】:

CASE 必须返回一个标量值,所以试试这个变体:

select PDADate, T.Merchandizer_ID, T.Merchandizer, Merchandizer_LoginName, STORE_ID, STORE_CODE, 
    STORE_NAME, ACCOUNT_ID, ACCOUNT_NAME, Account_Store_Format_Id, Account_Store_Format, 
    StoreType_Id, StoreType, T.Listid, T.Listname, T.TimeIn, T.TimeOut, T.PlannedDate, 
    T.Reason, TaskCode, TotalTime
from [dbo].Report_RD_Coverage T
inner join #TempLocationH TL on TL.LocationId = T.Location_Id
where CONVERT(date, PDADate) between (@Start_Date)
        and Isnull(@End_Date, @CurrentDate)
    and (
        @Account_Id is null
        or T.Account_Id in (
            select *
            from UDF_SplitString(@Account_Id, ',')
            )
        )
    and (
        @StoreType_Id is null
        or T.StoreType_Id in (
            select *
            from UDF_SplitString(@StoreType_Id, ',')
            )
        )
    and (
        @Store_Id is null
        or T.Store_Id in (
            select *
            from UDF_SplitString(@Store_Id, ',')
            ) end
        )

【讨论】:

    【解决方案2】:

    我试过这个并且非常接近,但你必须从我找到的链接中做一些事情。 这是我的尝试。您唯一需要构建的是@udf 数据。

    declare @Store_Id INT;
    declare @Account_Id INT;
    DECLARE @UDF[9] OF VARCHAR(30);
    set @Store_Id = 99 --NULL  
    set @Account_Id = 15  
    SET @UDF = '11,12,13,14,15,16'
    
    SELECT @Account_Id AS ACID
    WHERE CAST(@Account_Id AS VARCHAR(6)) IN (
       CASE WHEN @Store_Id IS NULL THEN CAST(@Account_Id AS VARCHAR(6)) 
       ELSE @UDF  END 
    

    链接在 http://www.codeproject.com/Questions/473174/CreateplusArrayplusinplusSqlplusServer

    DECLARE @INSTR as VARCHAR(MAX)
    SET @INSTR = '2,3,177,'
    DECLARE @SEPERATOR as VARCHAR(1)
    DECLARE @SP INT
    DECLARE @VALUE VARCHAR(1000)
    SET @SEPERATOR = ','
    CREATE TABLE #tempTab (id int not null)
    WHILE PATINDEX('%' + @SEPERATOR + '%', @INSTR ) <> 0 
    BEGIN
       SELECT  @SP = PATINDEX('%' + @SEPERATOR + '%',@INSTR)
       SELECT  @VALUE = LEFT(@INSTR , @SP - 1)
       SELECT  @INSTR = STUFF(@INSTR, 1, @SP, '')
       INSERT INTO #tempTab (id) VALUES (@VALUE)
    END
    SELECT * FROM myTable WHERE id IN **(SELECT id FROM #tempTab)**
    DROP TABLE #tempTab
    

    你可以提取粗体的sql和如何创建临时表及其数据的逻辑,我希望你能得到你想要的。

    【讨论】:

      【解决方案3】:

      >这是我正确的解决方案........现在它可以正常工作了

      CREATE TABLE #Store_Id (StoreID varchar(20))
      
          IF @Store_Id != '0'
          BEGIN 
              INSERT INTO #Store_Id
              SELECT data FROM UDF_SplitString(@Store_Id,',')     
          END
          ELSE
              BEGIN
                  INSERT INTO #Store_Id
                  SELECT '0'
          END
      
      CREATE TABLE #StoreType_Id (StoreTypeID varchar(20))
      
          IF @StoreType_Id != '0'
          BEGIN 
              INSERT INTO #StoreType_Id
              SELECT data FROM UDF_SplitString(@StoreType_Id,',')     
          END
          ELSE
              BEGIN
                  INSERT INTO #StoreType_Id
                  SELECT '0'
          END 
      
      CREATE TABLE #Account_Id (AccountID varchar(20))
      
          IF @Account_Id != '0'
          BEGIN 
              INSERT INTO #Account_Id
              SELECT data FROM UDF_SplitString(@Account_Id,',')       
          END
          ELSE
              BEGIN
                  INSERT INTO #Account_Id
                  SELECT '0'
          END     
      
      INSERT INTO #FinalTable(VisitDate,Merchandizer_Id,Merchandizer,MerchandizerLogin,StoreId,StoreCode,StoreName,AccountId,AccountName,
          Account_Store_Format_Id,Account_Store_Format,StoreTypeId ,StoreType ,ListId ,ListName,TimeIn ,TimeOut,PlannedDate ,Reason ,TaskCode,TotalTime)      
      
      SELECT  Visit_Date,T.Merchandizer_ID,T.Merchandizer,Merchandizer_LoginName,STORE_ID,STORE_CODE,STORE_NAME,ACCOUNT_ID,ACCOUNT_NAME,
              Account_Store_Format_Id,Account_Store_Format,StoreType_Id, 
              StoreType,T.Listid,T.Listname,T.TimeIn,T.TimeOut,T.PlannedDate,T.Reason,TaskCode,TotalTime 
      FROM [dbo].Report_RD_Coverage T
      INNER JOIN #TempLocationH TL ON TL.LocationId=T.Location_Id
      INNER JOIN #Store_Id on CONVERT(VARCHAR,t.Store_Id) = CASE WHEN @Store_Id = '0' THEN convert(VARCHAR,t.Store_Id) ELSE StoreID END
      INNER JOIN #StoreType_Id on CONVERT(VARCHAR,t.StoreType_Id) = CASE WHEN @StoreType_Id = '0' THEN convert(VARCHAR,t.StoreType_Id) ELSE StoreTypeID END
      INNER JOIN #Account_Id on CONVERT(VARCHAR,t.Account_Id) = CASE WHEN @Account_Id = '0' THEN convert(VARCHAR,t.Account_Id) ELSE AccountID END
      
      WHERE CONVERT(Date,PDADate) Between @Start_Date AND @End_Date
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-09
        • 1970-01-01
        • 1970-01-01
        • 2013-06-30
        • 1970-01-01
        • 1970-01-01
        • 2020-03-26
        相关资源
        最近更新 更多