Having issues getting this to work. Each query works individually however when I try to alias each Subquery to work the Join I get the error:
SQL Command not properly ended. Any suggestions would be extremely appreciated.
Select C.*
From
(
(
Select
a.*,
Row_Number() Over(Partition By referral_id Order By start_date,line) as rn
from hcclsc.referral_Bed_Day a
) A
Inner Join (
Select
a.referral_id,
max(rn) as vn
From (
Select
referral_id,
line,
bed_day_type_id,
start_date,
end_date,
Row_Number() Over(Partition by referral_id Order By start_date, line) as rn
From HCCLSC.referral_Bed_Day
) a
Group by referral_id
) B
On A.referral_ID = B.referral_id and a.rn = b.vn
) C
You're joining A to B, but then not selecting a anything from those joined subqueries.
This part:
Select C.*
From
(
(
would need to specify columns to select from the join; if you want all of them from both subqueries then:
Select C.*
From
(
Select *
From
(
but then that extra level of subquery isn't really adding anything, and you can remove the C level:
Select *
From
(
Select
a.*,
Row_Number() Over(Partition By referral_id Order By start_date,line) as rn
from hcclsc.referral_Bed_Day a
) A
Inner Join (
Select
a.referral_id,
max(rn) as vn
From (
Select
referral_id,
line,
bed_day_type_id,
start_date,
end_date,
Row_Number() Over(Partition by referral_id Order By start_date, line) as rn
From HCCLSC.referral_Bed_Day
) a
Group by referral_id
) B
On A.referral_ID = B.referral_id and a.rn = b.vn
try like below by using cte
with cte as
(
Select
a.referral_id
max(rn) as vn
From
(Select
referral_id
,line
,bed_day_type_id
,start_date
,end_date
,Row_Number() Over(Partition by referral_id Order By start_date, line) as rn
From
HCCLSC.referral_Bed_Day
) a Group by referral_id
), cte2 as
(
Select
a.*
,Row_Number() Over(Partition By referral_id Order By start_date,line) as rn
from
hcclsc.referral_Bed_Day a
) select A.*,B.* from cte A join cte2 B
on A.referral_ID = B.referral_id and A.vn= B.rn
Related
I have a query that runs as follows:
WITH teste1 as (
SELECT
CONCAT(a.pid, a.num_ordenado) as id_despacho,
a.pid,
a.created_at,
a.nota,
a.from_id,
a.from_nome
FROM (
SELECT pid, id,
(ROW_NUMBER() over (partition by pid order by created_at)) as num_ordenado,
from_id, from_nome, nota, created_at
FROM mytable_a) as a
),
teste2 as (
SELECT
CONCAT(t.pid, t.ordenado) as id_despacho,
t.ordenado,
t.pid as id_doc,
t.data as diahora,
CONCAT
(
'Evento: ', t.evento
) as conteudo2,
'' as pasta,
t.from_id,
t.from_nome,
t.to_id,
t.to_nome
FROM
(
SELECT pid, data,
(ROW_NUMBER() over (partition by pid order by data)) as ordenado,
from_id, from_nome, to_id, to_nome, evento
FROM mytable_t) as t
)
SELECT *
FROM teste2 as t2
LEFT JOIN teste1 as t1
ON t2.id_despacho = t1.id_despacho
WHERE t2.conteudo2 <> 'Evento: Campo bloqueado' AND t2.conteudo2 <> 'Evento: Campo desbloqueado'
In each CTE, I order the ID's by datetime and then create a new ID structure on which I join by that new ID at the last query. I'm wondering how could I do to now order them again by datetime.
My questions then would be:
Can I use the results of a CTE (teste1 and teste2 tables) inside a subquery? Something like this (not working)
SELECT
t2.id_despacho,
t2.id_doc,
t2.diahora,
t2.conteudo2,
t1.id_despacho,
t1.created_at,
t1.nota,
(ROW_NUMBER() OVER (PARTITION BY id_doc ORDER BY diahora, created_at)) AS ordenado_final
FROM
(SELECT *
FROM teste2 AS t2
LEFT JOIN teste1 AS t1 ON t2.id_despacho = t1.id_despacho
WHERE t2.conteudo2 <> 'Evento: Campo bloqueado'
AND t2.conteudo2 <> 'Evento: Campo desbloqueado')
Does that ROW_NUMBER() work like that? Can I order by two different columns?
(ROW_NUMBER() OVER (PARTITION BY id_doc
ORDER BY diahora, created_at)) AS ordenado_final
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
I want to assign the values from Table B to Table A, but so that each record in Table B occurs in the same number of repetitions.
Fiddle SQL
You can use window functions for this and mod arithmetic. For simple repetition:
with a as (
select a.*, rownum as seqnum
from a
),
b as (
select b.*, rownum as seqnum, count(*) over () as cnt
from b
)
select a.col, b.col
from a join
b
on mod(a.seqnum - 1, b.cnt) = b.seqnum - 1;
For more random assignment, randomize the seqnums:
with a as (
select a.*,
row_number() over (order by dbms_random.random) as seqnum
from a
order by db
),
b as (
select b.*, count(*) over () as cnt,
row_number() over (order by dbms_random.random) as seqnum
from b
)
select a.col, b.col
from a join
b
on mod(a.seqnum - 1, b.cnt) = b.seqnum - 1;
You can use the ROWNUM for achieving the same:
SELECT
COLOUR,
EMP
FROM
(
SELECT
COLOUR,
ROWNUM RN
FROM
T1
) T1,
(
SELECT
EMP,
ROWNUM RN
FROM
T2
) T2
WHERE
MOD(T1.RN, 2) + 1 = T2.RN
Fiddler SQL QUERY
Try this,
with Employees as
(select Emp, Row_Number() Over(order by 1) Rn
from B
cross join (select 1
from Dual
connect by level < (select count(1)
from A) / (select count(1)
from B) + 1)
order by Dbms_Random.Value),
Colours as
(select Colour, Rownum Rn
from A)
select t.Colour, k.Emp
from Colours t
join Employees k
on t.Rn = k.Rn
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
I need to JOIN a table named IB to the code below. I need to pull in the following fields from IB: QOO, QOH, QCM and AVG. The JOIN conditions are IJ.IJITEM = IB.IBITEM and IJ.IJLOC = IB.IBLOC
;WITH cte AS
(
SELECT IJLOC, IJITEM, IJDATE, IJLCGT,
rn = ROW_NUMBER() OVER (PARTITION BY IJITEM, IJLOC ORDER BY IJDATE DESC)
FROM dbo.IJ
)
SELECT IJLOC, IJITEM, IJDATE, IJLCGT
FROM cte WHERE rn = 1;
One method, which allows for a little more complexity than just JOINing the IB table to "cte" in your final SELECT is to nest another CTE using the current one as the table. For example:
;WITH cte AS
(
SELECT IJLOC, IJITEM, IJDATE, IJLCGT,
rn = ROW_NUMBER() OVER (PARTITION BY IJITEM, IJLOC ORDER BY IJDATE DESC)
FROM dbo.IJ
),
filtered AS (
SELECT IJLOC, IJITEM, IJDATE, IJLCGT
FROM cte
WHERE rn = 1
)
SELECT ib.QOO, ib.QOH, ib.QCM, ib.[AVG]
FROM ib
INNER JOIN filtered
ON filtered.IJITEM = IB.IBITEM
AND filtered.IJLOC = IB.IBLOC
Another option, depending on how the query optimizer handles the JOINs between all the tables, and if you don't need to return any of the fields from the IJ table, is to insert the results of your CTE into a temp table and then JOIN to that. For example:
CREATE TABLE #Temp (IJITEM DataType, IJLOC DataType)
;WITH cte AS
(
SELECT IJLOC, IJITEM, IJDATE, IJLCGT,
rn = ROW_NUMBER() OVER (PARTITION BY IJITEM, IJLOC ORDER BY IJDATE DESC)
FROM dbo.IJ
)
INSERT INTO #Temp (IJITEM, IJLOC)
SELECT IJITEM, IJLOC
FROM cte
WHERE rn = 1;
SELECT ib.QOO, ib.QOH, ib.QCM, ib.[AVG]
FROM ib
INNER JOIN #Temp tmp
ON tmp.IJITEM = IB.IBITEM
AND tmp.IJLOC = IB.IBLOC
;
WITH cte
AS ( SELECT IJLOC ,
IJITEM ,
IJDATE ,
IJLCGT ,
rn = ROW_NUMBER() OVER ( PARTITION BY IJITEM, IJLOC ORDER BY IJDATE DESC )
FROM dbo.IJ
)
SELECT IJLOC ,
IJITEM ,
IJDATE ,
IJLCGT ,
IB.QOO ,
IB.QOH ,
IB.QCM ,
IB.[AVG]
FROM cte
INNER JOIN IB ON cte.IJITEM = IB.IBITEM
AND cte.IJLOC = IB.IBLOC
WHERE cte.rn = 1 ;