简体   繁体   English

如何使用子查询更新表

[英]How can I update a table by using subquery

I have got table which is "Stocks".我有一张桌子,上面写着“股票”。 There are thousands of records inside of this table and I need to UPDATE it acc.该表中有数千条记录,我需要更新它。 to following Example.到以下示例。 (I use SQL Server 2008) (我使用 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

After executing the code, I want to have a table which is like:执行代码后,我想要一个表,如下所示:

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

What needs to happen here is that the SQL understands 001 - 002 and 003 are 3 different groups.这里需要发生的是 SQL 理解 001 - 002 和 003 是 3 个不同的组。 (I'm thinking about using SUBSTRING(stock_name,3,20) since the first 2 part of my text value will not be like " AA.002 ". Grouping will start from the third part of each stock name.) It selects the maximum a.id value and update the rows accordingly. (我正在考虑使用 SUBSTRING(stock_name,3,20) 因为我的文本值的前 2 部分不会像“ AA.002 ”。分组将从每个股票名称的第三部分开始。)它选择最大a.id值并相应地更新行。 I really need your help about this issue.我真的需要你在这个问题上的帮助。

Many thanks in advance!提前谢谢了!

Here is one possibility.这是一种可能性。 I used table variables for clarity.为了清楚起见,我使用了表变量。 You may want to stick some of this into sub-queries.您可能希望将其中的一些内容粘贴到子查询中。 But this should work right away.但这应该立即起作用。

-- 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

Is this what you want?这是你想要的吗?

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;

This will update a stock_name这将更新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'

First of all thank you all for your answers and supports.首先感谢大家的回答和支持。 Ken Palmer's input made this answer possible for which I appreciate him much. Ken Palmer 的投入使这个答案成为可能,我非常感谢他。 Here is the code which works perfectly:这是完美运行的代码:

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))

If you want to update all rows, the query below should work.如果你想更新所有行,下面的查询应该可以工作。

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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