How do I create a temp table using this snippet? - sql

how do i produce this SQL snippet as a temp table so I can join some other stuff into it?
with MyCTE AS
(
select *, RANK() OVER (PARTITION BY workplace ORDER BY Total DESC) AS Rank
from [dbo].[OriginDestination]
)
select * from MyCTE where Rank <= 5

Like this:
with MyCTE AS
(
select *, RANK() OVER (PARTITION BY workplace ORDER BY Total DESC) AS Rank
from [dbo].[OriginDestination]
)
select *
into #yourTempTable
from MyCTE
where Rank <= 5

Related

Compare Column A of Row 1 with Column B of Row 2 in Same table

I have a table name 'Table A' where I need to get the all values based on two columns 'AdviserBusinessId' and 'ClientcontactGuid' having count > 1. I am able to achieve this using self join as below query.
select gc.AdviserBusinessId,gc.ClientContactGuid,gc.PlanStartDate,gc.PlanEndDate,gc.ClientEngagementGuid, gc.RenewalGuid,
ROW_NUMBER() over(partition by gc.adviserbusinessid,gc.clientcontactguid order by gc.planenddate asc) as rownum from GENIUS_ClientEngagement gc
inner join(
select AdviserBusinessId,ClientContactGuid from GENIUS_ClientEngagement
group by AdviserBusinessId,ClientContactGuid having count(*) > 1) B
on gc.AdviserBusinessId = b.AdviserBusinessId and gc.ClientContactGuid = b.ClientContactGuid
And this is what the table looks like:
[![enter image description here][1]][1]
Now my main point is that, I want to compare PlanEndDate of row 1 with PlanStartDate of row 2 and get the rows if PlanEndDate > PlanStartDate. Let's take an example of above two rows, if suppose the planstartdate was < planenddate then I just want to populate those above two rows.
Will cursor or loop be helpful in this ?
Thanks in advance. Any suggestions will be appreciated.
Use analytic functions:
SELECT AdviserBusinessId,
ClientContactGuid,
PlanStartDate,
PlanEndDate,
ClientEngagementGuid,
RenewalGuid,
rn
FROM (
SELECT AdviserBusinessId,
ClientContactGuid,
PlanStartDate,
PlanEndDate,
ClientEngagementGuid,
RenewalGuid,
ROW_NUMBER() OVER (
PARTITION BY adviserbusinessid, clientcontactguid
ORDER BY planEndDate asc
) AS rn,
COUNT(*) OVER (
partition by adviserbusinessid, clientcontactguid
) AS num_rows,
LEAD(planStartDate) OVER (
PARTITION BY adviserbusinessid, clientcontactguid
ORDER BY planEndDate asc
) AS next_start,
LAG(planEndDate) OVER (
PARTITION BY adviserbusinessid, clientcontactguid
ORDER BY planEndDate asc
) AS prev_end
FROM GENIUS_ClientEngagement
) gce
WHERE num_rows > 1
AND ( (rn = 1 AND planEndDate > next_start)
OR (rn = 2 AND prev_end > planStartDate) )
You can use self join to achieve this. Something like this:
SELECT * FROM TableA A
LEFT JOIN TableA B ON A.ClientContactGuid = B.ClientContactGuid AND (A.RowNum+1) = B.RowNum
WHERE A.PlanEndDate>B.PlanStartDate OR B.PlanStartDate IS NULL
This was what I wanted, thanks to #MTO for the direction.
with cte
as(
select gc.AdviserBusinessId,gc.ClientContactGuid,gc.PlanStartDate,gc.PlanEndDate,gc.ClientEngagementGuid, gc.RenewalGuid,
ROW_NUMBER() over(partition by gc.adviserbusinessid,gc.clientcontactguid order by planenddate desc) as rownum
from GENIUS_ClientEngagement gc
inner join(
select AdviserBusinessId,ClientContactGuid from GENIUS_ClientEngagement
group by AdviserBusinessId,ClientContactGuid having count(*) > 1
) B
on gc.AdviserBusinessId = b.AdviserBusinessId and gc.ClientContactGuid = b.ClientContactGuid
)
select *,ROW_NUMBER() over(partition by adviserbusinessid,clientcontactguid order by planenddate asc) as rn,
LEAD(PlanStartDate) OVER (
PARTITION BY adviserbusinessid, clientcontactguid
ORDER BY planEndDate asc
) AS next_start,
LAG(planEndDate) OVER (
PARTITION BY adviserbusinessid, clientcontactguid
ORDER BY planEndDate asc
) AS prev_ends into #temp2 from cte
where rownum <=2
select AdviserBusinessId,ClientContactGuid,PlanStartDate,PlanEndDate,ClientEngagementGuid,RenewalGuid from #temp2 where
( (rn = 1 AND planEndDate > next_start)
OR (rn = 2 AND prev_ends > planStartDate) )
drop table #temp2

Creating column and filtering it in one select statement

Wondering if it is possible to creating a new column and filter on that column. The following is an example:
SELECT row_number() over (partition by ID order by date asc) row# FROM table1 where row# = 1
Thanks!
Some databases support a QUALIFY clause which you might be able to use:
SELECT *
FROM table1
QUALIFY ROW_NUMBER() OVER (PARTITION BY ID ORDER BY date) = 1;
On SQL Server, you may use a TOP 1 WITH TIES trick:
SELECT TOP 1 WITH TIES *
FROM table1
ORDER BY ROW_NUMBER() OVER (PARTITION BY ID ORDER BY date);
More generally, you would have to use a subquery:
WITH cte AS (
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY date) rn
FROM table1 t
)
SELECT *
FROM cte
WHERE rn = 1;
The WHERE clause is evaluated before the SELECT so your column has to exist before you can use a WHERE clause. You could achieve this by making a subquery of the original query.
SELECT *
FROM
(
SELECT row_number() over (partition by ID order by date asc) row#
FROM table1
) a
WHERE a.row# = 1

How to get MAX rownumber with rowNumber in same query

I have ROW_NUMBER() OVER (ORDER BY NULL) rnum in a sql statement to give me row numbers. is there a way to attach the max rnum to the same dataset going out?
what I want is the row_number() which I get, but I also want the MAXIMUM rownumber of the total return on each record.
SELECT
ROW_NUMBER() OVER (ORDER BY NULL) rnum,
C.ID, C.FIELD1, C."NAME", C.FIELD2, C.FIELD3
FROM SCHEMA.TABLE
WHERE (C.IS_CRNT = 1)
), MAX_NUM as (
SELECT DATA.ID, max(rnum) as maxrnum from DATA GROUP BY DATA.COMPONENT_ID
) select maxrnum, DATA.* from DATA JOIN MAX_NUM on DATA.COMPONENT_ID = MAX_NUM.COMPONENT_ID
DESIRED RESULT (ASSUMING 15 records):
1 15 DATA
2 15 DATA
3 15 DATA
etc...
I think you want count(*) as a window function:
SELECT ROW_NUMBER() OVER (ORDER BY NULL) as rnum,
COUNT(*) OVER () as cnt,
C.ID, C.FIELD1, C."NAME", C.FIELD2, C.FIELD3
FROM SCHEMA.TABLE
WHERE C.IS_CRNT = 1
Based on my assumptions in your dataset, this is the approach I would take:
WITH CTE AS (
select C.ID, C.FIELD1, C."NAME", C.FIELD2, C.FIELD3, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ID)
FROM SCHEMA.TABLE WHERE (C.IS_CRNT = 1))
SELECT *, (select count(*) from cte) "count" from cte;

Random records in Oracle table based on conditions

I have a Oracle table with the following columns
Table Structure
In a query I need to return all the records with CPER>=40 which is trivial. However, apart from CPER>=40 I need to list 5 random records for each CPID.
I have attached a sample list of records. However, in my table I have around 50,000 records.
Appreciate if you can help.
Oracle solution:
with CTE as
(
select t1.*,
row_number() over(order by DBMS_RANDOM.VALUE) as rn -- random order assigned
from MyTable t1
where CPID <40
)
select *
from CTE
where rn <=5 -- pick 5 at random
union all
select t2.*, null
from my_table t2
where CPID >= 40
SQL Server:
with CTE as
(
select t1.*,
row_number() over(order by newid()) as rn -- random order assigned
from MyTable t1
where CPID <40
)
select *
from CTE
where rn <=5 -- pick 5 at random
union all
select t2.*, null
from my_table t2
where CPID >= 40
How about something like this...
SELECT *
FROM (SELECT CID,
CVAL,
CPID,
CPER,
Row_number() OVER (partition BY CPID ORDER BY CPID ASC ) AS RN
FROM Table) tmp
WHERE CPER>=40 OR pids <= 5
However, this is not random.
Assuming that you want five additional random records, you can do:
select t.*
from (select t.*,
row_number() over (partition by cpid,
(case when cper >= 40 then 1 else 2 end)
order by dbms_random.value
) as seqnum
from t
) t
where seqnum <= 5 or cper >= 40;
The row_number() is enumerating the rows for each cpid in two groups -- based on the cper value. The outer where is taking all cper values in the range you want as well as five from the other group.

Trouble using ROW_NUMBER() OVER (PARTITION BY

I have this query :
SELECT
Reservation.*,
ROW_NUMBER() OVER (PARTITION BY code_bien ORDER BY (SELECT NULL)) AS RowNums
FROM
Reservation
WHERE
RowNums = 1
I get this error :
Msg 207, Level 16, State 1, Line 2
Invalid column name 'RowNums'.
I don't know where the problem is - any help?
You'd need to use a CTE:
WITH tempData AS
(
SELECT Reservation.*,
ROW_NUMBER() OVER (PARTITION BY code_bien ORDER BY (SELECT NULL)) AS RowNums
FROM Reservation
)
SELECT * FROM tempData WHERE RowNums = 1
However, a cleaner approach would be to use WITH TIES:
SELECT TOP 1 WITH TIES *
FROM Reservation
ORDER BY ROW_NUMBER() OVER (PARTITION BY code_bien ORDER BY (SELECT NULL))
You can't use RowNums directly,
Try like this,
SELECT *
FROM
(
SELECT Reservation.*,ROW_NUMBER() OVER (PARTITION BY code_bien ORDER BY (SELECT NULL)) AS RowNums
FROM Reservation
) S
where RowNums = 1
SELECT t.*
FROM
(SELECT Reservation.*,ROW_NUMBER() OVER (PARTITION BY code_bien ORDER BY NULL ) AS RowNums
FROM Reservation) t
where RowNums = 1
You cannot use this directly as this is not a column in the table. Either use CTE or derived table.
CTE
:WITH C AS (
SELECT Reservation.*,ROW_NUMBER() OVER (PARTITION BY code_bien ORDER BY (SELECT NULL)) AS RowNums
)
SELECT * FROM C WHERE RowNums = 1
Try this
;WITH CTE AS(
SELECT Reservation.*,
ROW_NUMBER() OVER (PARTITION BY code_bien ORDER BY (SELECT NULL)) AS RowNums
FROM Reservation)
SELECT * FROM CTE
WHERE RowNums = 1