我有(更复杂的版本)以下架构:
CREATE TABLE Messages (
ItemId INT IDENTITY PRIMARY KEY,
Name VARCHAR(20) NOT NULL,
DeliveryType INT NOT NULL
);
CREATE TABLE NotificationsQueue (
ItemId INT NOT NULL,
DeliveryType INT NOT NULL
);
DeliveryType的可能值为:
0 -> none
1 -> mail
2 -> email
3 -> both
现在,在Messages表中有一些条目:
INSERT INTO Messages(Name, DeliveryType) Values
('Test0', 0),
('Test1', 1),
('Test2', 2),
('Test3', 3)
我需要填充NotificationsQueue表,如下所示:
我尝试这样做导致了这两个问题:
INSERT INTO NotificationsQueue (ItemId, DeliveryType) SELECT ItemId, 1 AS DeliveryType FROM Messages WHERE DeliveryType IN (1, 3)
INSERT INTO NotificationsQueue (ItemId, DeliveryType) SELECT ItemId, 2 AS DeliveryType FROM Messages WHERE DeliveryType IN (2, 3)
即使这样可行,插入的select语句在实践中要复杂得多,所以我想知道是否有任何好方法可以在单个查询中合并它们,以避免重复。
PS:我不允许更改架构或在Messages
表中添加重复项。
答案 0 :(得分:1)
如果您可以使用触发器,则可以执行此操作
CREATE TRIGGER dbo.Messages_Inserted ON dbo.[Messages]
FOR INSERT
AS
INSERT INTO dbo.[NotificationsQueue]
( ItemId
,DeliveryType
)
SELECT ItemId
,1
FROM INSERTED
WHERE DeliveryType IN ( 1, 3 )
UNION ALL
SELECT ItemId
,2
FROM INSERTED
WHERE DeliveryType IN ( 2, 3 )
GO
INSERT INTO dbo.[Messages](Name, DeliveryType) Values
('Test0', 0),
('Test1', 1),
('Test2', 2),
('Test3', 3)
SELECT * FROM dbo.[Messages]
SELECT * FROM dbo.NotificationsQueue
答案 1 :(得分:1)
如果您只想要一个选择中的所有内容,我会创建一个查找表来翻译类型,就像这样
;WITH cte AS (SELECT * FROM (VALUES (1,1),(2,2),(3,1),(3,2)) a(DeliveryType,type))
SELECT ItemId, t.type AS DeliveryType
FROM Messages m
INNER JOIN cte t
ON t.DeliveryType = m.DeliveryType
答案 2 :(得分:0)
也许是这样的:
INSERT INTO NotificationsQueue (ItemId, DeliveryType)
select itemid, case when deliverytype = 3 then n else deliverytype end
from messages
inner join (values(1), (2)) x(n) on n <= case when deliverytype=1 then 2 else deliverytype end -1