简体   繁体   中英

SQL Server: Combine multiple insert statement into one

I need help combining these single SQL insert statement into one. Here is my code which works as individual statements:

        INSERT INTO [DBO].[QUEST] ([QUEST_ID], [QUEST_TEXT], [DOM_ID], [CRT_USR], [CRT_DATE], [EXAM_ID], [RANDOMNUMBER]) SELECT TOP 24 [QUEST_ID], [QUEST_TEXT], [DOM_ID], @USR_NAME, @CRT_DATE, [EXAM_ID], ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) AS [RANDOMNUMBER] FROM [DBO].[QUEST] WHERE [DOM_ID] = 'DOM1' AND EXAM_ID = @EXAM_ID ORDER BY [RANDOMNUMBER]

        INSERT INTO [DBO].[QUEST] ([QUEST_ID], [QUEST_TEXT], [DOM_ID], [CRT_USR], [CRT_DATE], [EXAM_ID], [RANDOMNUMBER]) SELECT TOP 10 [QUEST_ID], [QUEST_TEXT], [DOM_ID], @USR_NAME, @CRT_DATE, [EXAM_ID], ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) AS [RANDOMNUMBER] FROM [DBO].[QUEST] WHERE [DOM_ID] = 'DOM2' AND EXAM_ID = @EXAM_ID ORDER BY [RANDOMNUMBER]

        INSERT INTO [DBO].[QUEST] ([QUEST_ID], [QUEST_TEXT], [DOM_ID], [CRT_USR], [CRT_DATE], [EXAM_ID], [RANDOMNUMBER]) SELECT TOP 15 [QUEST_ID], [QUEST_TEXT], [DOM_ID], @USR_NAME, @CRT_DATE, [EXAM_ID], ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) AS [RANDOMNUMBER] FROM [DBO].[QUEST] WHERE [DOM_ID] = 'DOM3' AND EXAM_ID = @EXAM_ID ORDER BY [RANDOMNUMBER]

        INSERT INTO [DBO].[QUEST] ([QUEST_ID], [QUEST_TEXT], [DOM_ID], [CRT_USR], [CRT_DATE], [EXAM_ID], [RANDOMNUMBER]) SELECT TOP 8 [QUEST_ID], [QUEST_TEXT], [DOM_ID], @USR_NAME, @CRT_DATE, [EXAM_ID], ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) AS [RANDOMNUMBER] FROM [DBO].[QUEST] WHERE [DOM_ID] = 'DOM4' AND EXAM_ID = @EXAM_ID ORDER BY [RANDOMNUMBER]

How do i combine these statements as one statement?

Use UNION ALL

    INSERT INTO [DBO].[QUEST] ([QUEST_ID], [QUEST_TEXT], [DOM_ID], [CRT_USR], [CRT_DATE], [EXAM_ID], [RANDOMNUMBER])
    SELECT TOP 24 [QUEST_ID], [QUEST_TEXT], [DOM_ID], @USR_NAME, @CRT_DATE, [EXAM_ID], ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) AS [RANDOMNUMBER] FROM [DBO].[QUEST] WHERE [DOM_ID] = 'DOM1' AND EXAM_ID = @EXAM_ID 
    UNION ALL
    SELECT TOP 24 [QUEST_ID], [QUEST_TEXT], [DOM_ID], @USR_NAME, @CRT_DATE, [EXAM_ID], ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) AS [RANDOMNUMBER] FROM [DBO].[QUEST] WHERE [DOM_ID] = 'DOM2' AND EXAM_ID = @EXAM_ID 
    UNION ALL 
    SELECT TOP 24 [QUEST_ID], [QUEST_TEXT], [DOM_ID], @USR_NAME, @CRT_DATE, [EXAM_ID], ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) AS [RANDOMNUMBER] FROM [DBO].[QUEST] WHERE [DOM_ID] = 'DOM3' AND EXAM_ID = @EXAM_ID 
    UNION ALL
    SELECT TOP 24 [QUEST_ID], [QUEST_TEXT], [DOM_ID], @USR_NAME, @CRT_DATE, [EXAM_ID], ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) AS [RANDOMNUMBER] FROM [DBO].[QUEST] WHERE [DOM_ID] = 'DOM4' AND EXAM_ID = @EXAM_ID 

I am late, but I can suggest another approach to achieve this like following.

;WITH MT AS 
(
 SELECT * FROM (VALUES 
    ('DOM1', 24),('DOM2', 10),('DOM3', 15),('DOM4', 8)
    )T(DOM_ID ,[Count])
)

INSERT INTO [DBO].[QUEST] (COLUME1, COLUM2...)
SELECT COLUME1, COLUM2... FROM
(
  SELECT *, ROW_NUMBER() OVER (PARTITION BY DOM_ID ORDER BY [RANDOMNUMBER]) RN
  FROM [DBO].[QUEST] 
) TBL
INNER JOIN MT MT ON TBL.DOM_ID = MT.DOM_ID 
WHERE TBL.RN <=MT.[Count]

Or simpally like following.

INSERT INTO [DBO].[QUEST] (COLUME1, COLUM2...)
SELECT COLUME1, COLUM2... FROM
(
  SELECT *, ROW_NUMBER() OVER (PARTITION BY DOM_ID ORDER BY [RANDOMNUMBER]) RN  FROM [DBO].[QUEST] 
) TBL
INNER JOIN
(
  SELECT * FROM (VALUES ('DOM1',24),('DOM2',10),('DOM3',15),('DOM4',8)) T(DOM_ID,[Count])
) MT ON TBL.DOM_ID = MT.DOM_ID 
WHERE TBL.RN <=MT.[Count]

You can check a demo implementation on http://rextester.com/CECHM83488

Here is one method, using ROW_NUMBER() and TOP WITH TIES :

INSERT INTO [DBO].[QUEST] ([QUEST_ID], [QUEST_TEXT], [DOM_ID], [CRT_USR], [CRT_DATE], [EXAM_ID], [RANDOMNUMBER])
    SELECT TOP (24) WITH TIES [QUEST_ID], [QUEST_TEXT], [DOM_ID], @USR_NAME, @CRT_DATE, [EXAM_ID], ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) AS [RANDOMNUMBER]
    FROM [DBO].[QUEST]
    WHERE [DOM_ID] IN ('DOM1', 'DOM2', 'DOM3', 'DOM4') AND
          EXAM_ID = @EXAM_ID
    ORDER BY ROW_NUMBER() OVER (PARTITION BY DOM_ID, RANDOMNUMBER);

It seems strange to be including the random number in QUEST . This would work just as well without the number.

Also note that the WHERE condition on DOM_ID is not necessary, so this can work on any number of them, without listing them explicitly.

You could use a WHILE loop to dynamically range your DOM from 1 to n. It should include the following. (obviously, this needs to be enhanced)

DECLARE @Var1 VARCHAR (10)
SET @Var1 = 'DOM'

DECLARE @Var2 INT 
SET @Var2 = 1

SELECT @Var1 + CAST (@Var2 AS VARCHAR)  -- that would be your DOM_ID

Order by Dom_ID, Randomnumber:

INSERT INTO [DBO].[QUEST] ([QUEST_ID], [QUEST_TEXT], [DOM_ID], [CRT_USR], [CRT_DATE], [EXAM_ID], [RANDOMNUMBER]) 
SELECT TOP 24 [QUEST_ID], [QUEST_TEXT], [DOM_ID], @USR_NAME, @CRT_DATE, [EXAM_ID], ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) AS [RANDOMNUMBER] 
FROM [DBO].[QUEST] 
WHERE [DOM_ID] = 'DOM1' AND EXAM_ID = @EXAM_ID 
UNION ALL
SELECT TOP 10 [QUEST_ID], [QUEST_TEXT], [DOM_ID], @USR_NAME, @CRT_DATE, [EXAM_ID], ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) AS [RANDOMNUMBER] 
FROM [DBO].[QUEST] 
WHERE [DOM_ID] = 'DOM2' AND EXAM_ID = @EXAM_ID 
UNION ALL
SELECT TOP 15 [QUEST_ID], [QUEST_TEXT], [DOM_ID], @USR_NAME, @CRT_DATE, [EXAM_ID], ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) AS [RANDOMNUMBER] 
FROM [DBO].[QUEST] 
WHERE [DOM_ID] = 'DOM3' AND EXAM_ID = @EXAM_ID 
UNION ALL
SELECT TOP 8 [QUEST_ID], [QUEST_TEXT], [DOM_ID], @USR_NAME, @CRT_DATE, [EXAM_ID], ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) AS [RANDOMNUMBER] 
FROM [DBO].[QUEST] 
WHERE [DOM_ID] = 'DOM4' AND EXAM_ID = @EXAM_ID 
ORDER BY DOM_ID, [RANDOMNUMBER]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM