How to Update multiple columns with using ABS,DATEDIFF - sql

DECLARE
#deviationtime int,
#actualtime datetime,
#estimatedtime datetime
While (Select TOp 1 successrate FROM YBS_Tahmin_Kayit where deviationtime = 999 order by recordtime desc) = 999
BEGIN
SET #actualtime= (SELECT Top 1 actualtime From [TTS].[dbo].YBS_Tahmin_Kayit where deviationtime = 999 order by recordtime Desc )
SET #estimatedtime = (SELECT Top 1 estimatedtime From [TTS].[dbo].YBS_Tahmin_Kayit where deviationtime = 999 order by recordtime Desc )
SET #deviationtime = ABS(DATEDIFF(second, #actualtime, #estimatedtime))
Update [TTS].[dbo].YBS_Tahmin_Kayit SET deviationtime = #deviationtime where deviationtime = 999 and estimatedtime= #estimatedtime
end
I SETTED ALL deviationtime = 999 in database.
I want update all deviation time from database but my code making 1 by 1.

Related

Update subsequent row data if the first line has been updated in SQL

How to update the subsequent row if the data at first row has the changes made?
How to construct a proper SQL query for this situation?
ID ACTION ORIBALANCE TRANAMOUNT NEWBALANCE
1, Deposit, 1000, 100,1100
2,Deposit,1100,300,1400
3,Deposit,1400,500,1900
4,Withdraw,1900,-300,1600
5,Withdraw,1600,-500,1100
If I update the row ID 1, I changed the tranamount from 100 to 500, so the newbalance will be updated to 1500. RowID 2 will update its oribalance from 1100 to 1500. It is cummulative.
Expected result
ID ACTION ORIBALANCE TRANAMOUNT NEWBALANCE
1, Deposit, 1000, 500,1600
2,Deposit,1600,300,1900
3,Deposit,1900,500,2400
4,Withdraw,2400,-300,2100
5,Withdraw,2100,-500,1600
If I got it correctly, you want to update every row according to the change amount.
DECLARE #ChangeAmount INT = 500
DECLARE #ID INT = 1
UPDATE DataTable SET
ORIBALANCE = ORIBALANCE + ( CASE WHEN #ID > ID THEN #ChangeAmount ELSE 0 END ),
NEWBALANCE = NEWBALANCE + #ChangeAmount
WHERE ID >= #ID
You can update it with a workflow kind of
-- Start updating row id = 2 for example
declare #id int = 2;
update t set TRANAMOUNT = 500
where id = #id;
-- and update following rows
declare #startb int = (select top(1) ORIBALANCE from t
where id = #id);
with c as
(
select id, action, ORIBALANCE, TRANAMOUNT, NEWBALANCE
, s = #startb + sum(TRANAMOUNT) over(order by id) - TRANAMOUNT
, n = #startb + sum(TRANAMOUNT) over(order by id)
from t
where id >= #id
)
update c
set ORIBALANCE = s, NEWBALANCE = n;
But I advise against that because a single row updates triggers blocking the whole table.
Consider creating a view for ORIBALANCE, NEWBALANCE data.
You seem to want a cumulative sum and adding in the first value:
select ID, ACTION, TRANAMOUNT,
(sum(TRANAMOUNT) over (order by id) -
TRANAMOUNT +
first_value(ORIBALANCE) over (order by id)
) as new_oribalance
from t;
You can easily put this into an update:
with toupdate as (
select t.*
(sum(TRANAMOUNT) over (order by id) -
TRANAMOUNT +
first_value(ORIBALANCE) over (order by id)
) as new_oribalance
from t
)
update toupdate
set oribalance = new_oribalance
where oribalance <> new_oribalance;

Update query with order by

I am trying to update one column based on another column short. I am using order by, but while using select top(10000) my incremental number going 4000 series but I need from 101, but initially I declare int 100
DECLARE #IncrementValue int
SET #IncrementValue = 100
UPDATE CabecDoc
SET CDU_NumberBook = #IncrementValue,
#IncrementValue = #IncrementValue + 1
FROM
(SELECT TOP(7000) *
FROM CabecDoc
WHERE data BETWEEN '2019-05-01' AND '2019-07-17'
AND Entidade = 'VD4'
AND tipodoc = 'VD' AND CDU_SimbolBook = '*'
ORDER BY NumDoc ASC) CabecDoc
I need update column from 101 to an incremental number through 7000 records.
Here's what you need. No need to declare variables.
UPDATE
CabecDoc
SET
CDU_NumberBook = 100 + RowNum
FROM
(
Select
top(7000) *,
ROW_NUMBER() OVER(
ORDER BY
NumDoc
) AS RowNum
FROM
CabecDoc
WHERE
data between '2019-05-01'
and '2019-07-17'
and Entidade = 'VD4'
and tipodoc = 'VD'
and CDU_SimbolBook = '*'
ORDER BY
RowNum ASC
) CabecDoc

sql select into select in function

When I try to alter the function below I get the following error message:
Only one expression can be specified in the select list when the
subquery is not introduced with EXISTS.
I guess it is probably because of select into select. But why does this select into select work separately ( not in function ) but not in function.
ALTER FUNCTION [dbo].[Getcurrentexchangerate] (#CurrencyFromId INT,
#CurrencyToId INT)
returns DECIMAL(13, 10)
AS
BEGIN
DECLARE #rate DECIMAL (13, 10)
DECLARE #dw INT
SET #dw = (SELECT Datepart(dw, Getdate()))
IF( #dw != 2 ) -- Monday
BEGIN
SET #rate = (SELECT TOP (1) [rate]
FROM currencyconversionrate
WHERE [currencyfromid] = #CurrencyFromId
AND [currencytoid] = #CurrencyToId
ORDER BY id DESC)
END
ELSE
BEGIN
SET #rate = (SELECT *
FROM (SELECT TOP(2) Row_number()
OVER (
ORDER BY id DESC) AS
rownumber,
rate
FROM currencyconversionrate
WHERE ( [currencyfromid] = 2
AND [currencytoid] = 5 )
ORDER BY id DESC) AS Rate
WHERE rownumber = 2)
END
IF( #rate IS NULL )
BEGIN
SET #rate = 1
END
RETURN #rate
END
See your "else" part
SET #rate = (SELECT *
FROM (SELECT TOP(2) Row_number()
OVER (
ORDER BY id DESC) AS
rownumber,
rate
FROM currencyconversionrate
WHERE ( [currencyfromid] = 2
AND [currencytoid] = 5 )
ORDER BY id DESC) AS Rate
WHERE rownumber = 2)
You're trying to select all fields from currencyconversionrate table, you can't do that, or do you want to select "RATE" column only?
Try changing to below:
SET #rate = (SELECT rate
FROM (SELECT TOP(1) Row_number()
OVER (
ORDER BY id DESC) AS
rownumber,
rate
FROM currencyconversionrate
WHERE ( [currencyfromid] = 2
AND [currencytoid] = 5 )
ORDER BY id DESC) AS Rate
WHERE rownumber = 2)

SQL Query to retrieve the last records till the quantity purchased reaches the total quantity in stock

I have a table that have the ItemCode and Quantity in stock and another table that contains the purchases.
I want a query to get the Quantity in stock (ex. Qty = 5) and to take the purchase table to get the purchase invoices by descending order and take the Item Prices.
The Query has to keep retrieving records from the Purchase table according to the Quantity till we reach sum of Quantity in stock = 5.
ex.
**Purchase No ItemCode Qty Cost Price**
2 123 2 100
3 123 10 105
6 123 2 100
8 123 1 90
9 123 2 120
---------------------------------------------
**ItemCode Qty in Stock**
123 5
--------------------------------------------
In this example I want the query to retrieve for me the last 3 invoices (9,8 and 6) because the Qty (2+1+2 = 5)
Is there any suggestion .
Thank you in advance
This script should do the job.
/* SQL SCRIPT BEGIN */
create table #tmp (PurchaseNo int, ItemCode int, Qty int)
insert into #tmp (PurchaseNo, ItemCode, Qty)
select
p1.PurchaseNo, p1.ItemCode, sum(t.Qty) as Qty
from
Purchases p1
join
(
select
p2.PurchaseNo,
p2.ItemCode, p2.Qty
from
Purchases p2
) t on p1.PurchaseNo <= t.PurchaseNo and p1.ItemCode = t.ItemCode
group by p1.PurchaseNo, p1.ItemCode
order by p1.ItemCode, sum(t.Qty) asc
select * From #tmp
where
ItemCode = 123
and
Qty < 5
union
select top 1 * From #tmp
where
ItemCode = 123
and
Qty >= 5
order by PurchaseNo desc
drop table #tmp
/* SQL SCRIPT END */
Hi This can be the solution :
Here I have Used Result Table which will store the result.
I have used three tables Purchage(PurchageNo,ItemCode,Qty) , Stock(ItemCode,QtyInStock) and result(PurchageNo).
Full Workable Code is Here:
DECLARE #ItemCode int;
DECLARE #AvailableQty int;
SET #ItemCode = 123 ;
SET #AvailableQty = (select QtyInStock from Stock where ItemCode = #ItemCode);
SELECT
RowNum = ROW_NUMBER() OVER(ORDER BY PurchageNo),*
INTO #PurchageTemp
FROM Purchage
DECLARE #MaxRownum INT;
SET #MaxRownum = (select COUNT(*)from #PurchageTemp);
DECLARE #Iter INT;
SET #Iter = 1;
DECLARE #QtySum int=0;
DECLARE #QtySumTemp int=0;
DECLARE #CurrentItem int;
WHILE (#Iter <= #MaxRownum and #QtySum <= #AvailableQty)
BEGIN
set #QtySumTemp=#QtySum;
set #QtySumTemp = #QtySumTemp + (SELECT Qty FROM #PurchageTemp WHERE RowNum = #Iter and ItemCode=#ItemCode);
IF #QtySumTemp <= #AvailableQty
BEGIN
set #QtySum=#QtySumTemp;
set #CurrentItem= (SELECT PurchageNo FROM #PurchageTemp WHERE RowNum = #Iter and ItemCode=#ItemCode);
insert into [Result] values (#CurrentItem);
END
SET #Iter = #Iter + 1
END
DROP TABLE #PurchageTemp

How to check the previous and next row values

Using SQL Server 2000
table1
id date value
001 23/03/2012 P
001 24/03/2012 A
001 25/03/2012 P
001 26/03/2012 P
....
I want to check previous row and next row value by date wise, if it is P, then i want to make a current row P
expected output
id date value
001 23/03/2012 P
001 24/03/2012 P 'Updated as per the condition
001 25/03/2012 P
001 26/03/2012 P
....
How to make a query for the above condition
Need Query Help
Have a look at the example script below.
DECLARE #Table TABLE(
ID VARCHAR(20),
[Date] DATETIME,
Value VARCHAR(10)
)
INSERT INTO #Table SELECT '001','23/Mar/2012','P'
INSERT INTO #Table SELECT '001','24/Mar/2012','A'
INSERT INTO #Table SELECT '001','25/Mar/2012','P'
INSERT INTO #Table SELECT '001','26/Mar/2012','P'
SELECT *
FROM #Table
UPDATE #Table
SET Value = 'P'
FROM #Table t
WHERE t.Value = 'A'
AND
(
SELECT TOP 1
Value
FROM #Table tBelow
WHERE t.ID = tBelow.ID
AND t.Date > tBelow.Date
ORDER BY tBelow.Date DESC
) = 'P' --Previous
AND (
SELECT TOP 1
Value
FROM #Table tBelow
WHERE t.ID = tBelow.ID
AND t.Date < tBelow.Date
ORDER BY tBelow.Date
) = 'P' --Next
SELECT *
FROM #Table
-- Input parameters
declare #cur_id char(3)
declare #cur_dt datetime
set #cur_id = '001'
set #cur_dt = '2012-03-25'
-- Search previous/next row
declare #prev_dt datetime
declare #next_dt datetime
select #prev_dt = max(date)
from YourTable
where id = #cur_id
and date < #cur_dt
and value = 'A'
select #next_dt = min(date)
from YourTable
where id = #cur_id
and date > #cur_dt
and value = 'A'
-- Update previous/next row if found
update YourTable
set value = 'P'
where id = '001'
and date in (#prev_dt, #next_dt)