T SQL Update rows using max function - sql-server

With this query what I need SQL to do is update a column value based on another column so that it grabs the most recent MAX ID.
select
max(T1id), t1.v_code
from
[Table1] T1
join
[Table2] t2 on t1.T1Code = t2.T2Code
where
t2.active = 0
and t1.t1activesw = 0
and t1.mapping not like '%selected%'
group by
t1.v_code
I'd like to join the select to the table on the version code id = max(t1.v_code) and then use the code as a sub select just not sure how to finish it.

With this, you get all data from the row for with the highest T1.id for each T1.v_code:
;WITH CTE as
(
SELECT
T1.*,
row_number() over (partition by T1.v_code order by T1.id desc) rn
FROM
[Table1] T1
JOIN
[Table2] t2 on t1.T1Code = t2.T2Code
WHERE
t2.active = 0
and t1.t1activesw = 0
and t1.mapping not like '%selected%'
)
SELECT *
FROM CTE
WHERE rn = 1
Edit: In order to update, replace(as requested in commment)
SELECT *
FROM CTE
WHERE rn = 1
with
UPDATE CTE
SET columnname = 'newvalue'
WHERE rn = 1
this

Related

Postgresql - Update CTE result from CTE Output?

I need to update CTE o/p one of the column value (top 1 record) based on the latest timestamp & then return.
Query
WITH cte AS (
select
dt_zone.zone_name,
dt_material_status.mtstatus_name,
dt_historicalzone.visit_time_in
FROM ((public.dt_historicalzone
INNER JOIN dt_material_status
ON dt_historicalzone.mtstatus_id = dt_material_status.mtstatus_id)
INNER JOIN dt_zone ON dt_historicalzone.zone_id = dt_zone.zone_id)
WHERE material_id = 'ELS46885'
ORDER BY dt_historicalzone.zone_id DESC)
UPDATE cte SET cte.mtstatus_name = true WHERE SELECT * FROM cte LIMIT 1;
SELECT * FROM cte
You may try using an update join, with Postgres' syntax, including a CTE for the limit portion of the query:
WITH cte AS (
SELECT dh.mtstatus_id
FROM dt_historicalzone dh
INNER JOIN dt_zone dz
ON dh.zone_id = dz.zone_id
ORDER BY zone_id DESC
LIMIT 1
)
UPDATE dt_material_status d
SET mtstatus_name = true
FROM cte t
WHERE d.mtstatus_id = t.mtstatus_id AND
d.material_id = 'ELS46885';
when you update a CTE, the background table is getting updated. You can have only one statement below CTE. Post that CTE loses its scope. You can only go for UPDATE statement, post CTE. I have modified the CTE and updated the top 1 row.
The above statement is applicable for SQL Server. In Postgres, the CTE cannot be target of UPDATE statements. See the below error in Postgres.
Query Error: error: relation "cte" cannot be the target of a modifying
statement
WITH cte AS (
select top 1
dt_zone.zone_name,
dt_material_status.mtstatus_name,
dt_historicalzone.visit_time_in
FROM public.dt_historicalzone
INNER JOIN dt_material_status
ON dt_historicalzone.mtstatus_id = dt_material_status.mtstatus_id
INNER JOIN dt_zone ON dt_historicalzone.zone_id = dt_zone.zone_id
WHERE material_id = 'ELS46885'
ORDER BY dt_historicalzone.zone_id DESC)
UPDATE cte
SET mtstatus_name = true
I have tried with sample data for a CTE update. Below works fine in SQL Server.
create table #test(a int)
create table #test2(a int, b int)
insert into #test values (1)
insert into #test2 values (1,1)
;WITH CTE as
(
select top 1 t.a, t2.b
FROM #test as t
join #test2 as t2
on t.a = t2.a
order by t.a desc
)
update cte set b = 0
select * from #test2

Cross apply MSSQL operator equivalent in bigquery

is there an equivalent to cross apply in Sql server syntaxe or in bigquery syntaxe.
I need to write this query without the cross apply:
select *
from t1
cross apply (select top 1 col1,col2,col3
from t2
where col1 = t1.col1
and (col2 = '0' or col2 = t1.col2)
and (col3 = '0' or (col3 = left(t1.col3) and t1.col4 = 'fr'))
order by col2 desc, col3 desc)
t1 called 'Delivery' contains deliveries informations:
Delivery_ID,Delivery_ShipmentDate,Country_Code,address_ZipCode and the providerservice_id
t2 called 'ProviderService' contains informations about the providerservice:
Providerservice_id,DCountry_ID , DZone_Code as well as a numeric ProviderService_DeliveryTime.
So each Delivery_ID has a ProviderService_ID
And For the same Providerservice we could have several distinct ProviderService_DeliveryTime according to the other columns in this table(DCountry_ID , DZone_Code)
So the final query will be:
Select t1.Delivery_ShipmentDate,t2.ProviderService_DeliveryTime
from Delivery t1
cross apply (select top 1 ProviderService_DeliveryTime,DCountry_ID , DZone_Code
from ProviderService
where ProviderService_id = t1.ProviderService_id
And (DCountry_ID = '0' or DCountry_ID = t1.Country_Code)
And (DZone_Code = '0' or (DZone_Code = left(t1.address_ZipCode,2) and t1.Country_Code='FR'))
order by t2.DCountry_ID desc, t2.DZone_Code desc)sq
In fact I need first to write the same query in sql server syntaxe and then to write it in Bigquery because BigQuery don't recognize "cross apply" operator.
I tried to do it with row_number window function but it did not work:
with cte as (Select t1.Delivery_ShipmentDate,t2.ProviderService_DeliveryTime,row_number() over (partition by t2.providerservice_id order by t2.DCountry_ID desc, t2.DZone_Code desc) as num
from Delivery t1
inner join providerservice t2 on t1.providerservice_id = t2.providerservice_id
And (DCountry_ID = '0' or DCountry_ID = t1.Country_Code)
And (DZone_Code = '0' or (DZone_Code = left(t1.address_ZipCode,2) and t1.Country_Code='FR')))
select * from cte where num = 1
it works only when I filter by delivery_id:
with cte as (Select t1.Delivery_ShipmentDate,t2.ProviderService_DeliveryTime,row_number() over (partition by t2.providerservice_id order by t2.DCountry_ID desc, t2.DZone_Code desc) as num
from Delivery t1
inner join providerservice t2 on t1.providerservice_id = t2.providerservice_id
And (DCountry_ID = '0' or DCountry_ID = t1.Country_Code)
And (DZone_Code = '0' or (DZone_Code = left(t1.address_ZipCode,2) and t1.Country_Code='FR'))
where delivery_id = xxxx)
select * from cte where num = 1
Can any one help me please? Thanks!!
Below is for BigQuery Standard SQL
#standardSQL
SELECT * EXCEPT(pos)
FROM (
SELECT *
ROW_NUMBER() OVER(PARTITION BY TO_JSON_STRING(t1) ORDER BY t2.col2 DESC, t2.col3 DESC) pos
FROM t1 INNER JOIN t2
ON t2.col1 = t1.col1
AND (t2.col2 = '0' OR t2.col2 = t1.col2)
AND (t2.col3 = '0' OR (t2.col3 = left(t1.col3) AND t1.col4 = 'fr'))
)
WHERE pos = 1
I wish you gave us some data to play with - but having absence of it - above is just quick shot for you to try
I checked this approach (of implementing CROSS APPLY in BigQuery) against classic example with customers and orders tables and it worked
Would correlated subquery work the same as cross apply?
select *
from t1 , (select col1,col2,col3
from t2
where col1 = t1.col1
and (col2 = '0' or col2 = t1.col2)
and (col3 = '0' or (col3 = left(t1.col3) and t1.col4 = 'fr'))
order by col2 desc, col3 desc
limit 1)

Merge two rows into one and sum a column

THIS IS NOT ASKING HOW TO USE SUM() AND GROUP BY
I have two rows in tableA
ID VALUE
1 100
1 200
I want tableA:
ID VALUE
1 300
Note that I want to
delete the original two records in tableA
and replace them by the new record in tableA
Is this related to merge function?
I only want to work on tableA, don't want to create any new tables.
How about MERGE:
;with cte as (
select t.*,
row_number() over (partition by id order by id) as rn,
sum(value) over (partition by id) as total_value
from your_table t
)
merge into cte as t
using cte as t2
on (
t.id = t2.id
and t.rn = t2.rn
and t.rn = 1
)
when matched then update set t.value = t2.total_value
when not matched by source then delete;
Demo

Update two columns by another column of next row from same table in sql

Here is my table
And my output should be
I want to update the closed_date,time for new_class_desc ='FLM' with next Update_date,Update_time but if new_class_desc is 'FollowupComments' then ignore it and update the next date as Closed_date
I was trying query somewhat like this..
;WITH cte as(
SELECT *
,row_number() OVER(ORDER BY Update_date,Update_time) rn
FROM Table
WHERE Problem_sid = 1435819
)
UPDATE c1 SET Closed_date = c2.Update_date, Closed_time = c2.Update_time
FROM cte c1
JOIN cte c2 ON c1.rn = c2.rn - 1
AND c1.New_class_desc = 'FLM'
AND c2.New_class_desc <> 'FLM'
AND c2.New_class_desc not in ('FollowUpComments')
But in this I am not getting new_class_desc =Bank update_date as Closed_date for Flm.
Please guide here.
WITH cte
AS
(
SELECT *, ROW_NUMBER() OVER(ORDER BY t.Update_date, t.Update_time) AS rno
FROM my_Table t
WHERE t.New_class_desc <> 'FollowUpComments'
)
UPDATE t
SET t.Closed_Date = t1.Closed_Date,
t.Closed_Time = t1.Closed_Time
FROM cte t
JOIN cte t1 ON t.rno = t1.rno + 1
WHERE t.New_class_desc = 'FLM'

How to get rows with Maximum id with condition of a table in SQL Server

i have a table similar this
id-value-RowInid
1-xy-1
1-xx-2
1-xz-3
2-xx-1
2-xr-2
3-xq-1
4-xa-1
4-xc-2
...
i need a function for this table with similar output to get maximum of RowInid in separated id group
1-xz-3
2-xr-2
3-xq-1
4-xc-2
...
You just need to use MAX(RowInid) with GROUP BY Id, value
SELECT ID, VALUE, MAX(RowInid) FROM myTable GROUP BY ID, VALUE
EDIT:
As you updated your question, you can get value field using sub-query like this:
SELECT ID, VALUE, RowInid
FROM myTable t1 WHERE RowInid =
(
SELECT MAX(RowInid) FROM myTable WHERE id = t1.id GROUP BY id
)
ORDER BY id ASC;
You can also achieve this using INNER JOIN like this:
SELECT t2.ID, VALUE, t2.RowInid FROM myTable t1
INNER JOIN
(
SELECT ID, MAX(RowInid) AS RowIniD FROM myTable GROUP BY ID
) AS t2
ON t1.ID = t2.ID AND t1.RowInid = t2.RowInid
ORDER BY t1.ID ASC;
See this SQLFiddle
See more about GROUP BY and MAX in SQL Server.
no need for group by or max at all
select id, value, rowinid from
( select *, row_number() over (partition by id, order by rowinid desc) rn from yourtable ) v
where rn = 1
Try with,
Use Sub Query to get Id, Value and Max RowInid,
SELECT m1.[Id],m1.Value, m1.RowInid
FROM [Practice].[dbo].[myTable] m1 WHERE RowInid = (SELECT MAX(m2.RowInid) FROM [Practice].[dbo].[myTable] m2 WHERE M1.Id = m2.Id GROUP BY Id)
above query return result like:
4-xx-2
3-xx-1
2-xx-2
1-xx-3
To Ascending this use,
SELECT m1.[id],m1.Value, m1.RowInid
FROM [Practice].[dbo].[myTable] m1 WHERE m1.RowInid = (SELECT MAX(m2.RowInid) FROM [Practice].[dbo].[myTable] m2 WHERE M2.id = m1.id GROUP BY id) ORDER BY m1.id ASC

Resources