如何使用子查询更新表

时间:2017-01-19 19:16:45

标签: sql sql-server tsql sql-update self-reference

我有桌子,"股票"。此表中有数千条记录,我需要更新它。以下示例。 (我使用SQL Server 2008)

STOCKS.stock_name     STOCKS.a_id
A.001                  0
B.001                  0
C.001                 20
A.002                  0
B.002                 10
A.003                  0

执行代码后,我希望有一个表格,如:

STOCKS.stock_name     STOCKS.a_id
A.001                 20
B.001                 20
C.001                 20
A.002                 10
B.002                 10
A.003                  0

这里需要做的是SQL理解001 - 002和003是3个不同的组。 (我考虑使用SUBSTRING(stock_name,3,20),因为我的文本值的前两部分不会像" AA.002 "。将从每个股票名称的第三部分开始。)它选择最大的 a.id 值并相应地更新行。我真的需要你对这个问题的帮助。

非常感谢提前!

5 个答案:

答案 0 :(得分:0)

这是你想要的吗?

update stocks s
    set id = (select max(s2.id) from stocks s2 where substring(s2.stock_name, 3, 20) = substring(s.stockname, 3, 20)
               )
    where s.id = 0;

答案 1 :(得分:0)

这是一种可能性。为清楚起见,我使用了表变量。您可能希望将其中一些内容添加到子查询中。但这应该马上就可以了。

-- Your example data for demonstration purposes.
CREATE TABLE #STOCKS (stock_name nvarchar(5), a_id int)
INSERT INTO #STOCKS (stock_name, a_id) VALUES ('A.001', 0)
INSERT INTO #STOCKS (stock_name, a_id) VALUES ('B.001', 0)
INSERT INTO #STOCKS (stock_name, a_id) VALUES ('C.001', 20)
INSERT INTO #STOCKS (stock_name, a_id) VALUES ('A.002', 0)
INSERT INTO #STOCKS (stock_name, a_id) VALUES ('B.002', 10)
INSERT INTO #STOCKS (stock_name, a_id) VALUES ('A.003', 0)

-- To capture the stock name fragments, and the maximum value for each name fragment.
DECLARE @StockValues TABLE (stock nvarchar(5), stockNameFrag nvarchar(5), stockValue int)
DECLARE @StockMaxValues TABLE (stockNameFrag nvarchar(5), stockMaxValue int)

-- Data captured in this variable gets used in the next subquery.
INSERT INTO @StockValues (stock, stockNameFrag, stockValue)
SELECT  s.stock_name, SUBSTRING(s.stock_name, 3, 20), s.a_id
FROM    #STOCKS s
ORDER BY s.a_id DESC

-- Now extract the maximum value for each name fragment in @StockValues.
INSERT INTO @StockMaxValues
SELECT  sv1.stockNameFrag, MAX(sv2.MaxValue)
FROM    @StockValues sv1
        INNER JOIN (
            SELECT stockNameFrag, MAX(stockValue) AS MaxValue
            FROM    @StockValues
            GROUP BY stockNameFrag
            ) sv2 ON sv1.stockNameFrag = sv2.stockNameFrag AND sv1.stockValue = sv2.MaxValue
GROUP BY sv1.stock, sv1.stockNameFrag

-- Store results you want
DECLARE @Stock TABLE (stock nvarchar(5), stockMaxValue int)
INSERT INTO @Stock (stock, stockMaxValue)
SELECT  s.stock_name, smv.stockMaxValue
FROM    #STOCKS s
        INNER JOIN @StockMaxValues smv ON smv.stockNameFrag = SUBSTRING(s.stock_name, 3, 20)

-- Now update the #STOCKS table with the max value for each stock.
UPDATE  s1
SET     s1.a_id = s2.stockMaxValue
FROM    #STOCKS s1
        INNER JOIN @Stock s2 ON s1.stock_name = s2.stock

SELECT * FROM #STOCKS

-- Cleanup from the demo table.
DROP TABLE #STOCKS

答案 2 :(得分:0)

这将更新stock_name

UPDATE s
SET s.a_id = (
        SELECT MAX(a_id) 
        FROM Stocks
        WHERE SUBSTRING(stock_name, 3, 20) = SUBSTRING(s.stock_name, 3, 20)
)
FROM Stocks s
WHERE SUBSTRING(s.stock_name, 3, 20) = '001'

答案 3 :(得分:0)

首先,谢谢大家的回答和支持。 Ken Palmer的意见使得这个答案成为可能,我非常感谢他。这是完美运作的代码:

DECLARE @MAXPRIM table (StockNameFrag nvarchar(20), StockValue int)


INSERT INTO @MAXPRIM(StockNameFrag, StockValue)
SELECT SUBSTRING(stock_name,3,20), Max(a_id)
FROM Stocks
Group By SUBSTRING(stock_name,3,20)

UPDATE STOCKS
set a_id = (select StockValue from @MAXPRIM where StockNameFrag =SUBSTRING(stock_name,3,20))

答案 4 :(得分:0)

如果要更新所有行,则下面的查询应该有效。

UPDATE s
SET s.a_id = b.max_value
FROM Stocks s
JOIN (
    SELECT SUBSTRING(stock_name, 3, 20) AS 'stock_name', MAX(a_id) 'max_value'
    FROM Stocks s
    GROUP BY  SUBSTRING(s.stock_name, 3, 20)
) b on b.stock_name = SUBSTRING(s.stock_name, 3, 20)