sql多个插入一个表,同时循环/迭代另一个表?

时间:2010-06-29 17:05:08

标签: sql database sybase

我有两个表“TempStore”和“Store”,它们的列名为“Items”。

“TempStore”表中有数据需要转移到“Store”表,只需要很少的修改。

我需要迭代“TempStore”数据(即项目)并插入Store ...

更具体地说:我如何迭代TempStore(在sql中)“对于'TempStore'中的每个项目,我需要在'Store'中存储2个或3个项目,只需稍加修改”,我该如何实现?< / p>

我想要做的是从“[SELECT * FROM TempStore]”获取每个rowdata并在“Store”中插入三条记录,并且能够更改“items”

4 个答案:

答案 0 :(得分:7)

尝试INSERT-SELECT:

INSERT INTO Store
        (col1, col2, col3...)
    SELECT
        col1, col2, col3...
        FROM TempStore
        WHERE ...

只需让SELECT为每个插入返回一行,并在Cols中生成所需的值。您可能需要CASE并加入另一个表来创建额外的行。

编辑根据评论,OP希望看到数字表格在行动

  

让我们说TempStore表有{Items,   成本,价格,ActualCost,ActualPrice}   但是在Store表中我需要存储   {物品,成本,价格}。 ActualCost   和来自TempStore datarow的ActualPrice   需要添加为另一行   在商店....(我希望这会   感觉)....无论如何,是解决方案   使用“WHILE-BEGIN-END”??

CREATE TABLE Numbers (Number int NOT NULL PRIMARY KEY)
INSERT INTO Numbers VALUES(1)
INSERT INTO Numbers VALUES(2)
INSERT INTO Numbers VALUES(3)


INSERT INTO Store
        (Items, Cost, Price)
    SELECT
        t.Items, t.Cost
            ,CASE
                 WHEN n.Number=1 THEN t.Price
                 WHEN n.Number=2 THEN t.ActualCost
                 ELSE t.ActualPrice
             END
        FROM TempStore         t
            INNER JOIN Numbers N ON n.Number<=3
        WHERE ...

你甚至可以使用UNION:

INSERT INTO Store
        (Items, Cost, Price)
    SELECT
        t.Items, t.Cost, t.Price
        FROM TempStore t
    UNION ALL
    SELECT
        t.Items, t.Cost, t.ActualCost
        FROM TempStore t
    UNION ALL
    SELECT
        t.Items, t.Cost, t.ActualPrice
        FROM TempStore t

Numbers表或UNION我们 WAY 比循环更好!

答案 1 :(得分:3)

好的,我认为KM提出了一个涉及“数字表”的出色解决方案。但是,VoodooChild在评论中要求我发布示例代码以建议在INSERT-SELECT周围使用WHILE-BEGIN-END。

我创建了两个表,如VoodooChild的Store和TempStore。

商店有列StoreID,StoreName,StoreState,StoreNumber。

TempStore有列TempStoreID,TempStoreName。

我预先填充了TempStoreName,其值为First,Second,Third和Fourth。

现在,我的SQL将在Store表中为TempStore表中的每个记录插入三条记录,以满足WHERE子句中的条件。这个条件是TempStoreName的长度,显然不是真实世界的例子。

DECLARE @counter int 
SET @counter = 0;
WHILE @counter < 3
BEGIN
INSERT INTO Store (StoreName, StoreState, StoreNumber)
    SELECT TempStoreName, 'AZ', @counter FROM TempStore WHERE LEN(TempStoreName) = 5
SET @counter = @counter + 1
END

应用于空Store表时的结果是:

StoreID StoreName   StoreState  StoreNumber
1           First       AZ          0
2           First       AZ          1
3           First       AZ          2
4           Third       AZ          0
5           Third       AZ          1
6           Third       AZ          2

所以,这种方法有效。它似乎符合VoodooChild的需求。它可能是也可能不是最佳选择,但我们不知道决策中还涉及其他因素,例如此操作将重复多少次。

答案 2 :(得分:1)

INSERT INTO Store ( SELECT * FROM TempStore UNION ALL SELECT * FROM TempStore )

上述语句将在商店中为TempStore中的每一行插入两行。您可以将SELECT *更改为您要对项目进行的任何修改。

答案 3 :(得分:1)

鉴于您的最新评论,这应该可以满足您的需求。一旦到达那里,您应该可以通过某种方式区分Stores表中的值。也许是一个“实际的”BIT专栏或类似的东西:

INSERT INTO Stores (item, cost, price, actual)
SELECT item, cost, price, 0
FROM TempStores
UNION ALL
SELECT item, actual_cost, actual_price, 1
FROM TempStores

如果您需要调整列(例如,将actual_price提高10%),那么您可以这样做:

INSERT INTO Stores (item, cost, price, actual)
SELECT item, cost, price, 0
FROM TempStores
UNION ALL
SELECT item, actual_cost, 1.1 * actual_price, 1
FROM TempStores
WHERE actual_cost IS NOT NULL

我还在第二个SELECT语句中添加了一个WHERE子句,以表明您可以过滤行。 WHERE子句只会影响第二个SELECT。所以,你也可以这样做:

INSERT INTO Stores (item, cost, price, actual)
SELECT item, cost, price, 0
FROM TempStores
WHERE cost IS NOT NULL
UNION ALL
SELECT item, actual_cost, 1.1 * actual_price, 1
FROM TempStores
WHERE actual_cost IS NOT NULL