【问题标题】:complex SQL INSERT not working复杂的 SQL INSERT 不起作用
【发布时间】:2014-10-22 14:59:26
【问题描述】:

我正在将数据从一个表中的 1 行 X 列迁移到另一个表中的 X 行。在第一个表中,多个布尔记录 AF.AdditionalFieldsBoolean15(以及 14、13、12 等)存储在一行中。我需要创建一行来表示每个“真实”布尔列。

我一直在使用以下代码,它可以完美执行,除了它只插入 1 条记录。当我在第二个代码块中运行 SELECT 语句时,我返回了 12 条记录。如何确保遍历所有记录?

BEGIN TRAN TEST

DECLARE @id uniqueidentifier = NEWID()
DECLARE @dest uniqueidentifier = 'AC34C8E5-8859-4E74-ACF2-54B3804AE9C9'
DECLARE @person uniqueidentifier

SELECT @person = GP.Oid FROM <Redacted>.GenericPerson AS GP

INNER JOIN <Redacted>.AdditionalFields AS AF
ON GP.AdditionalFields = AF.Oid

WHERE AF.AdditionalBoolean15 = 'true'

INSERT INTO <Redacted>.Referral (Oid, Destination, Person)
OUTPUT INSERTED.*
VALUES (@id, @dest, @person)

选择返回 12 条记录的语句

SELECT *
FROM WS_Live.dbo.GenericPerson AS GP
INNER JOIN WS_Live.dbo.AdditionalFields AS AF
ON GP.AdditionalFields = AF.Oid

WHERE AF.AdditionalBoolean15 = 'true'

|

|

|

|

|

|

-------------解决方案(编辑)--------

多亏了 M.Ali,我才能够应付数据透视表并制定出以下解决方案。只是想发布一些解释,以防将来有人需要。

INSERT INTO <Redacted>.Referral (Person, Destination, Oid)
OUTPUT INSERTED.*
SELECT   Person
       , Destination
       , NEWID() AS Oid
FROM     
(
    SELECT 
    GP.Oid AS Person, 
    AF.AdditionalBoolean15 AS 'AC34C8E5-8859-4E74-ACF2-54B3804AE9C9', 
    AF.AdditionalBoolean14 AS '7DE4B414-42E0-4E39-9432-6DC9F60A5512',
    AF.AdditionalBoolean8  AS '5760A126-AD15-4FF4-B608-F1C4220C7087',
    AF.AdditionalBoolean13 AS '4EFFB0FB-BB6C-4425-9653-D482B6C827AC',
    AF.AdditionalBoolean17 AS '0696C571-EEFA-4FE6-82DA-4FF6AB96CC98',
    AF.AdditionalBoolean4  AS 'FF381D63-A76C-46F1-8E2C-E2E3C69365BF',
    AF.AdditionalBoolean20 AS 'C371E419-4E34-4F46-B07D-A4533491D944',
    AF.AdditionalBoolean16 AS '1F0D1221-76D7-4F1F-BB7A-818BB26E0590',
    AF.AdditionalBoolean18 AS 'C6FD53A8-37B9-4519-A825-472722A158C9',
    AF.AdditionalBoolean19 AS 'BEBD6ED6-AF0A-4A05-A1C1-060B2926F83E'

    FROM <Redacted>.GenericPerson GP
    INNER JOIN <Redacted>.AdditionalFields AF
    ON GP.AdditionalFields = AF.Oid 

)AS cp

UNPIVOT 
( 
    Bool FOR Destination IN ([AC34C8E5-8859-4E74-ACF2-54B3804AE9C9],
                             [7DE4B414-42E0-4E39-9432-6DC9F60A5512],
                             [5760A126-AD15-4FF4-B608-F1C4220C7087],
                             [4EFFB0FB-BB6C-4425-9653-D482B6C827AC],
                             [0696C571-EEFA-4FE6-82DA-4FF6AB96CC98],
                             [FF381D63-A76C-46F1-8E2C-E2E3C69365BF],
                             [C371E419-4E34-4F46-B07D-A4533491D944],
                             [1F0D1221-76D7-4F1F-BB7A-818BB26E0590],
                             [C6FD53A8-37B9-4519-A825-472722A158C9],
                             [BEBD6ED6-AF0A-4A05-A1C1-060B2926F83E]) 
)AS up

WHERE Bool = 'true'
ORDER BY Person, Destination

首先,我不确定为什么顶部的 SELECT NEWID() 有效,我之前在尝试 SELECT NEWID() 时收到错误。

我觉得使用这样的语句有点创意 AF.AdditionalBoolean19 AS 'BEBD6ED6-AF0A-4A05-A1C1-060B2926F83E' 因为我插入的表需要来自另一个表的 GUID,该表表示纯文本“名称”。没有将每个列名链接到该 GUID 的表,所以我认为这是最好的方法,但我想知道是否有人能想到更好的方法。

【问题讨论】:

  • 你为什么一次做这一行?那里有特定的要求吗...看来您最好一次插入所有 12 行(哦,为一个好名字加分!)
  • 谢谢!!我试图一次完成所有 12 个,但我认为我做错了什么,因为它只执行一行。
  • 您基本上需要一个UNPIVOT 查询来取消透视您的AdditionalBooleanN 列。

标签: tsql insert pivot pivot-table unpivot


【解决方案1】:

一个演示如何取消旋转 AdditionalBooleanN 列,而不是逐行执行,只需使用 where 子句过滤结果并插入到预期的目标表中。

测试数据

DECLARE @TABLE TABLE 
       (ID INT , dest INT, Person INT, Bol1 INT, Bol2 INT, Bol3 INT)
INSERT INTO @TABLE VALUES 
(1 , 100 , 1 , 1 , 1 , 1) ,
(2 , 200 , 2 , 1 , 1 , 0) ,
(3 , 300 , 3 , 1 , 0 , 0) ,
(4 , 400 , 4 , 0 , 0 , 0) 

查询

-- INSERT INTO Destination_Table (ID , Dest, Person, bol_Column)
SELECT *                     --<-- Only select columns that needs to be inserted 
FROM @TABLE t
 UNPIVOT ( Value FOR Bool_Column IN (Bol1, Bol2, Bol3) )up
-- WHERE  Bool_Column  = ??

结果

╔════╦══════╦════════╦═══════╦═════════════╗
║ ID ║ dest ║ Person ║ Value ║ Bool_Column ║
╠════╬══════╬════════╬═══════╬═════════════╣
║  1 ║  100 ║      1 ║     1 ║ Bol1        ║
║  1 ║  100 ║      1 ║     1 ║ Bol2        ║
║  1 ║  100 ║      1 ║     1 ║ Bol3        ║
║  2 ║  200 ║      2 ║     1 ║ Bol1        ║
║  2 ║  200 ║      2 ║     1 ║ Bol2        ║
║  2 ║  200 ║      2 ║     0 ║ Bol3        ║
║  3 ║  300 ║      3 ║     1 ║ Bol1        ║
║  3 ║  300 ║      3 ║     0 ║ Bol2        ║
║  3 ║  300 ║      3 ║     0 ║ Bol3        ║
║  4 ║  400 ║      4 ║     0 ║ Bol1        ║
║  4 ║  400 ║      4 ║     0 ║ Bol2        ║
║  4 ║  400 ║      4 ║     0 ║ Bol3        ║
╚════╩══════╩════════╩═══════╩═════════════╝

【讨论】:

  • 我可以在前三列中使用(@id, @dest, @person) 吗?而且,我可以从&lt;Redacted&gt;.AdditionalFields 中选择AddtionalFieldsBooleanN,比如(@id, @dest, @person, AdditionalFieldsBoolean1, AdditionalFieldsBoolean2, AdditionalFieldsBoolean3) 吗?
  • 是的,您可以在将行插入表格时使用表格中的SELECT @id, @dest, @person, AddtionalFieldsBooleanN
  • 我想我很困惑,因为我需要“ID”作为 GUID,我从一个不是我的布尔值存储位置的表中选择“目标”,我没有需要记录布尔值。我无法执行包含 NEWID() 的 SELECT 语句
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-20
相关资源
最近更新 更多