Reputation: 193
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)
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. (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. I really need your help about this issue.
Many thanks in advance!
Upvotes: 0
Views: 13792
Reputation: 3257
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)
Upvotes: 0
Reputation: 2445
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
Upvotes: 1
Reputation: 193
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. 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))
Upvotes: 0
Reputation: 1269563
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;
Upvotes: 0
Reputation: 3257
This will update a 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'
Upvotes: 0