Update a table using CTE and NEWID() - sql-server

I want try update a table using random values from the same table, but the original table donĀ“t have a identity to follow or any other number column...
WITH cteTable1 AS (
SELECT
ROW_NUMBER() OVER (ORDER BY NEWID()) AS n,
ENDE_NO_Address
FROM TableX
)
UPDATE TableX SET ENDE_NO_Address = (
SELECT ENDE_NO_Address
FROM cteTable1
WHERE cteTable1.n = This is the problem...
tnks for the help

Guessing...
UPDATE TableX
SET ENDE_NO_Address = (
SELECT TOP 1 ENDE_NO_Address FROM TableX ORDER BY NEWID()
)

declare #T table(Col1 varchar(10))
insert into #T values (1),(2),(3),(4),(5)
;with cte as
(
select *,
row_number() over(order by newid()) as rn1,
row_number() over(order by Col1) as rn2
from #T
)
update C1 set
Col1 = C2.Col1
from cte as C1
inner join cte as C2
on C1.rn1 = C2.rn2
Edit:
WITH cte AS (
SELECT
ROW_NUMBER() OVER (ORDER BY NEWID()) AS n1,
ROW_NUMBER() OVER (ORDER BY (select 1)) AS n2,
ENDE_NO_Address
FROM TableX
)
update C1 set
ENDE_NO_Address = C2.ENDE_NO_Address
from cte as C1
inner join cte as C2
on C1.n1 = C2.n2

Related

Convert Script to CTE

Please, can you help me with this query?
SELECT
[festno], 2
FROM
dbo.V_sadad_isar
WHERE
[festno] IN (SELECT DISTINCT [festno]
FROM
(SELECT
[festno], ROW_NUMBER() OVER (PARTITION BY [festno] ORDER BY fisar DESC) AS rn
FROM
dbo.V_sadad_isar) T
GROUP BY festno
HAVING MAX(rn) = 1)
AND [darsad_janbaz] <> 50
Try this:
;with cte as (
SELECT [festno],
ROW_NUMBER() OVER (PARTITION BY [festno] ORDER BY fisar DESC) AS rn
FROM dbo.V_sadad_isar
), cte2 as (
SELECT DISTINCT [festno]
FROM cte
GROUP BY festno
HAVING MAX(rn) = 1
)
SELECT fastno, 2
FROM dbo.V_sadad_isar
WHERE festno IN (SELECT festno FROM cte2)
But it can be simplified to this:
;with cte as (
SELECT DISTINCT [festno]
FROM cte
GROUP BY festno
HAVING COUNT(*) = 1
)
SELECT fastno, 2
FROM dbo.V_sadad_isar
WHERE festno IN (SELECT festno FROM cte)

Unexpected result using CTE to perform a random join on two tables for all rows one-to-many

I am attempting to randomly join the rows of two tables (TableA and TableB) such that each row in TableA is joined to only one row in TableB and every row in TableB is joined to at least one row in TableA.
For example, a random join of TableA with 5 distinct rows and TableB with 3 distinct rows should result in something like this:
TableA TableB
1 3
2 1
3 1
4 2
5 1
However, sometimes not all the rows from TableB are included in the final result; so in the example above might have row 2 from TableB missing because in its place is either row 1 or 3 joined to row 4 on TableA. You can see this occur by executing the script a number of times and checking the result. It seems that it is necessary for some reason to use an interim table (#Q) to be able to ensure that a correct result is returned which has all rows from both TableA and TableB.
Can someone please explain why this is happening?
Also, can someone please advise on what would be a better way to get the desired result?
I understand that sometimes no result is returned due to a failure of some kind in the cross apply and ordering which i have yet to identify and goes to the point that I am sure there is a better way to perform this operation. I hope that makes sense. Thanks in advance!
declare #TableA table (
ID int
);
declare #TableB table (
ID int
);
declare #Q table (
RN int,
TableAID int,
TableBID int
);
with cte as (
select
1 as ID
union all
select
ID + 1
from cte
where ID < 5
)
insert #TableA (ID)
select ID from cte;
with cte as (
select
1 as ID
union all
select
ID + 1
from cte
where ID < 3
)
insert #TableB (ID)
select ID from cte;
select * from #TableA;
select * from #TableB;
with cte as (
select
row_number() over (partition by TableAID order by newid()) as RN,
TableAID,
TableBID
from (
select
a.ID as TableAID,
b.ID as TableBID
from #TableA as a
cross apply #TableB as b
) as M
)
select --All rows from TableB not always included
TableAID,
TableBID
from cte
where RN in (
select
top 1
iCTE.RN
from cte as iCTE
group by iCTE.RN
having count(distinct iCTE.TableBID) = (
select count(1) from #TableB
)
)
order by TableAID;
with cte as (
select
row_number() over (partition by TableAID order by newid()) as RN,
TableAID,
TableBID
from (
select
a.ID as TableAID,
b.ID as TableBID
from #TableA as a
cross apply #TableB as b
) as M
)
insert #Q
select
RN,
TableAID,
TableBID
from cte;
select * from #Q;
select --All rows from both TableA and TableB included
TableAID,
TableBID
from #Q
where RN in (
select
top 1
iQ.RN
from #Q as iQ
group by iQ.RN
having count(distinct iQ.TableBID) = (
select count(1) from #TableB
)
)
order by TableAID;
See if this gives you what you're looking for...
DECLARE
#CountA INT = (SELECT COUNT(*) FROM #TableA ta),
#CountB INT = (SELECT COUNT(*) FROM #TableB tb),
#MinCount INT;
SELECT #MinCount = CASE WHEN #CountA < #CountB THEN #CountA ELSE #CountB END;
WITH
cte_A1 AS (
SELECT
*,
rn = ROW_NUMBER() OVER (ORDER BY NEWID())
FROM
#TableA ta
),
cte_B1 AS (
SELECT
*,
rn = ROW_NUMBER() OVER (ORDER BY NEWID())
FROM
#TableB tb
),
cte_A2 AS (
SELECT
a1.ID,
rn = CASE WHEN a1.rn > #MinCount THEN a1.rn - #MinCount ELSE a1.rn end
FROM
cte_A1 a1
),
cte_B2 AS (
SELECT
b1.ID,
rn = CASE WHEN b1.rn > #MinCount THEN b1.rn - #MinCount ELSE b1.rn end
FROM
cte_B1 b1
)
SELECT
A = a.ID,
B = b.ID
FROM
cte_A2 a
JOIN cte_B2 b
ON a.rn = b.rn;

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'

update column of all rows of table

I have 1 table with 500 rows, and another table with 750 rows or so. What I'm doing is, I'm getting a random 500 rows of a certain column from the second table, and I want to update a newly added column on the first table with those 500 values.
I know how to do updates that look like this:
UPDATE schema.table1
SET column = cl.column FROM schema.table1 cl
INNER JOIN table2 cf ON cf.column = cl.column
but I don't have any columns that are matching in both tables. Is there a way to do this without having to match the columns on the inner join?
so basically, I want to update 500 rows of 1 column in one table, with 500 values coming from another table
You can do it by using ROW_NUMBER to generate column to join two tables. take a look at the example and the output
DECLARE #T1 TABLE ( column1 INT ,column2 VARCHAR(2) )
DECLARE #T2 TABLE ( column1 VARCHAR(2) )
INSERT INTO #T1 ( column1, column2 )
VALUES ( 0, 'A' ), ( 1, 'B' ), ( 2, 'C' )
INSERT INTO #T2 ( column1 )
VALUES ( 'D'),( 'F'),( 'G' )
SELECT *, ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY (SELECT NULL) ) AS RN FROM #T1
SELECT *, ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY (SELECT NULL) ) AS RN FROM #T2
;WITH CTE_1 AS (SELECT *, ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY (SELECT NULL) ) AS RN FROM #T1)
,cte_2 AS (SELECT *, ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY (SELECT NULL) ) AS RN FROM #T2)
UPDATE t1
SET t1.column2 = t2.column1
FROM CTE_1 t1
JOIN cte_2 t2
ON t1.rn = t2.rn
SELECT *, ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY (SELECT NULL) ) AS RN FROM #T1
SELECT *, ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY (SELECT NULL) ) AS RN FROM #T2

How to optimize the query, adding rowNumber in where clause

In a table I have more than 700,000 records. When I run this query it takes more than 3 minutes to fetch the rows, and returns 390 records based on rowNum. Is there way to optimize this query?
SELECT ID, Lat, Long, SDateTime,
row_number() OVER (partition BY [ID] ORDER BY [SDateTime] DESC) AS rowNum
into #temp
FROM
dbo.myTable WITH (NOLOCK)
select * from #temp where rowNum = 1 -- returns 390 records
drop table #temp
Can I select data in one query without putting it in temp table? like this:
SELECT ID, Lat, Long, SDateTime,
row_number() OVER (partition BY [ID] ORDER BY [SDateTime] DESC) AS rowNum
FROM
dbo.myTable WITH (NOLOCK)
where (row_number() OVER (partition BY [ID] ORDER BY [SDateTime] DESC)) = 1
try doing this !
select * from
(
SELECT ID, Lat, Long, SDateTime,
row_number() OVER (partition BY [ID] ORDER BY [SDateTime] DESC) AS rowNum
FROM
dbo.myTable WITH (NOLOCK)
)x
where x.rowNum=1
This should do the job, but it will work very well with an index on (id,SDateTime)
;with d as (
select distinct id
from myTable
)
select
mt.*
from d
cross apply (
select top 1 *
from myTable m
on m.id = d.id
order by [SDateTime] DESC
) mt

Resources