在case语句中选择命令

时间:2015-07-08 08:48:40

标签: sql sql-server sql-server-2008

我在SQL Server 2008中遇到以下查询的错误

  

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

我想在THEN

之后的case语句中使用select命令

以下是查询

DECLARE @startTime DATETIME
    ,@endTime DATETIME
    ,@personId VARCHAR(max)
    ,@supplierId UNIQUEIDENTIFIER = NULL

SET @startTime = '2011-1-22'
SET @endTime = '2012-1-27'
SET @personId = '2dd3cd60-4acc-4ff1-9956-2938099c08af,69186022-78b5-4bc6-9878-55b14a44a5aa,e64f0bf8-51cc-4c85-a4bd-2615d3ba7a52,53091d8b-2891-4c46-babd-1f0036ffe003,ea21226c-8be6-48de-a707-fe0edd0b62a3,f5ce7a19-a8da-4c0c-a233-861f9330361b'

DECLARE @table TABLE (personId UNIQUEIDENTIFIER)

INSERT INTO @table
SELECT deviceid
FROM [dbo].[Split](@personId, ',')

CREATE TABLE #tempTable (
    PERSON_ID UNIQUEIDENTIFIER
    ,ASSET_ID UNIQUEIDENTIFIER
    ,EVENT_TYPE_ID INT
    ,EVENT_START_DATE DATETIME
    ,EVENT_DATE DATETIME
    ,AMEND_TIME INT
    ,GRP INT
    ,SEQ INT identity(1, 1)
    ,ACTIVITY_TIME INT
    )

--Adding Raw data to TEMP table    
INSERT INTO #tempTable
SELECT ASSET_EVENT.PERSON_ID
    ,ASSET_ID
    ,Event_Type_id
    ,EVENT_START_DATE
    ,Event_date
    ,ISNULL(DATEDIFF(ss, event_start_date, Event_date), 0) AS INTERVAL
    ,0
    ,0
FROM ASSET_EVENT
INNER JOIN PERSON ON ASSET_EVENT.PERSON_ID = PERSON.PERSON_ID
WHERE event_type_id < 3
    AND EVENT_DATE >= @startTime
    AND EVENT_DATE <= @endTime
    AND ASSET_EVENT.PERSON_ID IN (
        CASE (LEN(@personId))
            WHEN 0
                THEN ASSET_EVENT.PERSON_ID
            ELSE (
                    SELECT deviceid
                    FROM [dbo].[Split](@personId, ',')
                    )
            END
        )
    AND ISNULL(CONVERT(VARCHAR(40), PERSON.SUPPLIER_ID), '') = CASE 
        WHEN @supplierId IS NOT NULL
            THEN CONVERT(VARCHAR(36), @supplierId)
        ELSE ''
        END
ORDER BY person_id
    ,event_date

SELECT *
FROM #tempTable

DROP TABLE #tempTable

此查询的任何替代方案。

3 个答案:

答案 0 :(得分:0)

编辑此行

and  ASSET_EVENT.PERSON_ID in ( CASE (LEN(@personId)) WHEN 0 THEN ASSET_EVENT.PERSON_ID ELSE (select deviceid from [dbo].[Split]( @personId , ',')) END ) 

and
(
    @personId = ''
    OR 
    EXISTS
    ( 
        select *from [dbo].[Split]( @personId , ',') 
        where deviceid = ASSET_EVENT.PERSON_ID
    )
)

答案 1 :(得分:0)

尝试更改select这样的查询。

SELECT ASSET_EVENT.PERSON_ID,
       ASSET_ID,
       Event_Type_id,
       EVENT_START_DATE,
       Event_date,
       Isnull(Datediff(ss, event_start_date, Event_date), 0) AS INTERVAL,
       0,
       0
FROM   ASSET_EVENT
       INNER JOIN PERSON
               ON ASSET_EVENT.PERSON_ID = PERSON.PERSON_ID
WHERE  event_type_id < 3
       AND EVENT_DATE >= @startTime
       AND EVENT_DATE <= @endTime
       AND ( Len(@personId) = 0
             OR ASSET_EVENT.PERSON_ID IN (SELECT deviceid
                                           FROM   [dbo].[Split](@personId, ',')) )
       AND Isnull(CONVERT(VARCHAR(40), PERSON.SUPPLIER_ID), '') = CASE
                                                                    WHEN @supplierId IS NOT NULL THEN CONVERT(VARCHAR(36), @supplierId)
                                                                    ELSE ''
                                                                  END 

答案 2 :(得分:0)

where的那部分重组为:

AND (LEN(@personId) = 0
    OR ASSET_EVENT.PERSON_ID IN (
        SELECT deviceid
        FROM [dbo].[Split](@personId, ',')
    )