Fetch latest date records with group by - sql

I am trying to fetch the records with latest records with unique report_ids (col_1_0_ ).
Possible group by col_1_0_ and fetch the latest of that group record using this column col_10_0_ timestamp.
I tried to search this forum to find the way but it did not worked for me . It will be helpful if anyone help me to find the similar thread or help to make to get the results.
col_1_0_|ppi_event_id|col_2_0_ |col_10_0_ |
--------|------------|--------------------------|-----------------------|
149056| 3249|Draft |2020-08-25 13:01:49.016|
149056| 3249|Submitted | 2020-08-25 13:10:22.01|
149056| 3249|Submitted to administrator|2020-08-25 13:12:39.367|
149056| 3249|Validated |2020-08-25 13:13:28.879|
149060| 3249|Submitted to administrator|2020-08-25 13:32:41.924|
The expected result is
col_1_0_|ppi_event_id|col_2_0_ |col_10_0_ |
--------|------------|--------------------------|-----------------------|
149056| 3249|Validated |2020-08-25 13:13:28.879|
149060| 3249|Submitted to administrator|2020-08-25 13:32:41.924|
Anyone help in this regard.
Update : I have tried the solution mentioned below but sometimes it shows the first record "Draft" rather than "Validated"
Any other option to try ?

In Postgres, I would recommend using distinct on: that's a nice extension to the SQL standard, that was built exactly for the purpose you describe.
select distinct on (col_1_0) t.*
from mytable t
order by col_1_0, col_10_0_ desc

Traditional SQL format is to use row_number()
Demo
SELECT * FROM (
SELECT A.*,
ROW_NUMBER() OVER( PARTITION BY col_1_0_ ORDER BY col_10_0_) AS RN
FROM TABLE1 A ) X WHERE RN = 1;

Related

How can I display only the 1st line when I have multiple tables involved?

SELECT A.numeClient, A.CNP, A.Adresa, count(B.Eveniment) AS NR_EVE,B.Agent
FROM client A , eveniment B
WHERE A.CNP=B.CNP --AND ROWNUM =1
GROUP BY A.numeClient, A.CNP, A.Adresa,B.Agent
ORDER BY count(B.Eveniment) desc --LIMIT 1;
I want to display the client with the highest amount of events from table eveniment B and the rest of the info. I tried with rownum, but it doesn't work. Also tried with LIMIT 1, but that is out of the window since I need to use Oracle SQL 9. Is there any way around ? I tried using multiple Select, but I don't know how to make it work.
Well, I managed to solve it.
SELECT * FROM
(
SELECT A.numeClient, A.CNP, A.Adresa, count(B.Eveniment) AS NR_EVE,B.Agent
FROM client A , eveniment B
WHERE A.CNP=B.CNP --AND ROWNUM BETWEEN 1 AND 2
GROUP BY A.numeClient, A.CNP, A.Adresa,B.Agent
ORDER BY count(B.Eveniment) desc )
WHERE ROWNUM=1;

Sybase only Last Value

I'm looking for a solution for this case:
select pimpfung.idpatientklinik, pimpfung.idpatient_vaccination, pimpfung.datum
From ictq.pimpfung
order by pimpfung.idpatientklinik
Output is:
idpatientklinik;idpatient_vaccination;datum
1;5500;01.02.2001
1;5567;05.09.2003
3;7766;22.08.2005
3;8899;25.09.2006
3;8900;29.09.2006
But I want the output like this:
1;5567;05.09.2003
3;8900;29.09.2006
(only the last values sort by "pimpfung.datum" desc)
How to do that ?
Thank you and sorry for my bad english ;-)
You can use a correlated subquery:
select p.*
from pimpfung p
where p.datum = (select max(p2.datum)
from pimpfung p2
where p2.idpatientklinik = p.idpatientklinik
);
With an index on (idpatientklinik, datum) this is often the fastest approach.
Here is a db<>fiddle (which uses SQL Server but this is all standard SQL).

Getting error "SQL compilation error: Unsupported subquery type cannot be evaluated"

Am new to Snowflake programming though I had much experience in Oracle DB.
When am running the below query in Snowflake am getting the error as
SQL compilation error: Unsupported subquery type cannot be evaluated
SELECT organization_id,
inventory_item_id,
revision,
effectivity_date,
revision_label,
revision_id
FROM cg1_mtl_item_revisions_b mir
WHERE effectivity_date IN
(SELECT FIRST_VALUE (ir2.effectivity_date)
OVER (ORDER BY ir2.effectivity_date DESC)
effectivity_date
FROM cg1_mtl_item_revisions_b ir2
WHERE ir2.inventory_item_id = mir.inventory_item_id
AND ir2.organization_id = mir.organization_id
AND ir2.effectivity_date <= CURRENT_DATE
AND ir2.implementation_date IS NOT NULL)
AND mir.revision IN
(SELECT FIRST_VALUE (ir3.revision)
OVER (ORDER BY ir3.revision DESC)
revision
FROM cg1_mtl_item_revisions_b ir3
WHERE ir3.inventory_item_id = mir.inventory_item_id
AND ir3.organization_id = mir.organization_id
AND ir3.implementation_date IS NOT NULL
AND ir3.effectivity_date = mir.effectivity_date);
Am I missing something here??
Can someone plz help me here.
Thanks in Advance,
Sudarshan
The Snowflake database doesn't support correlated subqueries as extensively as Oracle does.
You have to find a way to rewrite, eg. using
WITH <common table expressions ...>
SELECT ...
JOIN ...
You seem to want the latest revision from the latest effective date. Window functions are probably a better approach in any database:
SELECT mir.* -- whatever columns you want
FROM (SELECT mir.*,
ROW_NUMBER() OVER (PARTITION BY mir.inventory_item_id, mir.organization_id
ORDER BY mir.effectivity_date DESC, mir.revision DESC) as seqnum
FROM cg1_mtl_item_revisions_b mir
) mir
WHERE seqnum = 1;
I have figured out that the third condition of the join in the last sub-query is throwing this error. If we comment out the following line then the code returns data:
{ AND ir3.effectivity_date = mir.effectivity_date }
So it seems three join conditions in a sub-query are not getting supported.
We need to work out on finding an alternate piece of code to satisfy the above condition so that we get the correct result set.
Another approach may be to use lateral joins - https://docs.snowflake.com/en/sql-reference/constructs/join-lateral.html
One important thing about lateral joins is it will only return matched records.

How to use “Partition By” or “Max”? for SQL Server

I have a very similar question to what was asked here for an Oracle DB (but I have an SQL Server 2012). The example I have used as a starter is based on the answer given here.
What I have is these four columns:
[L2] ,[DateofReporting],[L3] and [ServerName] more or less at a random day data is added to that table, but if it is, it will always be the same [L2],[DateofReporting],[L3] but with a different [ServerName]
Now I want to extract that data to give me all the servers [ServerName], which were added last for all months and years grouped by L2, L3 and the related month and year (coming from [DateofReporting]) .
SELECT [ID],[L2],[DateofReporting],[L3],[ServerName]
FROM (
select *,
max([DateofReporting])
OVER (PARTITION BY YEAR([DateofReporting]),
Month([DateofReporting])) maxdate
from [EADATAGOV].[Governance].[ToDos]
)max_date
where [DateofReporting] = maxdate
The problem I am phasing is, that the data is incomplete and their is obviously a bug in my statement. By now I don't see the tree for the forest, could you please help me clean up that SQL statement, or if there is a smarter way of doing it, I am open to suggestions.
I was thinking about utilizing ROW_NUMBER() to mark the relevant entries and than do a select on them, but I have never worked with that before.
thx Jan
example of output:
ID L2 DateofReporting L3 name
18214 Summer 2017-09-20 cloud BINHAS01105 <--
18215 Summer 2017-09-20 lightbulb BINHAS60276 <--
18217 Summer 2017-09-20 lightbulb CNAHAS62003 <--
15297 Summer 2017-09-15 cloud CINHAS01105
15298 Summer 2017-09-15 boat CINHAS60277
15300 Summer 2017-09-15 lightbulb DNAHAS62003
10512 Summer 2017-08-20 lightbulb DNAHAS62003 <--
the ones pointed out, are the ones I would expect to see in the result. As eg. boat does not have a newer entry than that of the 09-15.
new approach:
Select [L2],
MAX([DateofReporting]) LDateOfTest
from [EADATAGOV].[Governance].[ToDos]
group by [L2], YEAR([DateofReporting]), Month([DateofReporting]) ,[DType]
having DType= 'test'
order by LDateOfTest desc, L2 desc
This provides me (correctly) the latest date for each L2 for every month. Now in theory I should be able to use another query on the very same table where L2 and the LDateOfTest match.
My idea of a subselect does not work, as I can only pass one criteria, not two. But I don't know how that works, can you help me with the join(?) ?
It's difficult understand your request, since you didn't post any sample data (input).
As far as I understood, may be we can start from this query. Can you try it and pls let me know?
SELECT ID
,L2
,DATEOFREPORTING
,L3
,SERVERNAME
FROM(
SELECT ID
,L2
,DATEOFREPORTING
,L3
,SERVERNAME
,ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY DATEOFREPORTING DESC) RN
FROM TODOS
) A
WHERE RN = 1;
Select [ID],[L2],[DateofReporting],[L3],[ServerName]
From(
Select [ID],[L2],[DateofReporting],[L3],[ServerName],
Row_NUmber() Over(Partition BY [ServerName],[L3] Order BY [DateofReporting] Desc) as Row_Num
from [EADATAGOV].[Governance].[ToDos]
) Temp
Where Row_Num = 1
That's the solution I have come up with after some hours of struggling. I had to completely reset my approach.
IF OBJECT_ID('tempdb..#tmp_table') IS NOT NULL DROP TABLE #tmp_table
Select [L2],
MAX([DateofReporting]) LDateOfTest
into #tmp_table --(L2t, LDateOfTest)
from [EADATAGOV].[Governance].[ToDos]
group by [L2], YEAR([DateofReporting]), Month([DateofReporting]) ,[DType]
having DType = 'test'
order by LDateOfTest desc, L2 desc
SELECT [ID]
,[EADATAGOV].[Governance].[ToDos].[L2] L2f
,YEAR([DateofReporting]) YoT, Month([DateofReporting]) MoT
,[L3]
,[ServerName]
FROM [EADATAGOV].[Governance].[ToDos]
right join #tmp_table tt on tt.L2 = [EADATAGOV].[Governance].[ToDos].[L2] and tt.LDateOfTest = ToDos.DateofReporting
where DType = 'test'
order by DateofReporting desc, L3 asc
DROP TABLE #tmp_table
It probably isn't the prettiest solution, but it get's me the results I was hoping for.

How to Avoid Duplicate ID's In Access SQL

I have a problem that I hope you can help me.
I have the next query on Access SQL.
SELECT
ID_PLAN_ACCION, ID_SEGUIMIENTO,
Max(FECHA_SEGUIMIENTO) AS MAX_FECHA
FROM
SEGUIMIENTOS
WHERE
(((ID_PLAN_ACCION) = [CODPA]))
GROUP BY
ID_PLAN_ACCION, ID_SEGUIMIENTO;
And it returns this information:
ID_PLAN_ACCION ID_SEGUIMIENTO MAX_FECHA
-----------------------------------------------
A1-01 1 16/01/2014
A1-01 2 30/01/2014
But I really need that it throws off this:
ID_PLAN_ACCION ID_SEGUIMIENTO MAX_FECHA
----------------------------------------------
A1-01 2 30/01/2014
As you can see I only need the record that has the most recently date, not all the records
The GROUP BY doesn't work.
Please can you tell me what can I do? I am new on all this.
Thank you so much!!
PD: Sorry for my english, I'm learning
This will produce the results you want:
SELECT ID_PLAN_ACCION, max(ID_SEGUIMIENTO) as ID_SEGUIMIENTO, Max(FECHA_SEGUIMIENTO) AS MAX_FECHA
FROM SEGUIMIENTOS
WHERE ID_PLAN_ACCION = [CODPA]
GROUP BY ID_PLAN_ACCION;
I removed id_sequiimiento from the group by and added an aggregation function to get the max value. If the ids increase along with the date, this will work.
Another way to approach this query, though, is to use top and order by:
SELECT top 1 ID_PLAN_ACCION, ID_SEGUIMIENTO, FECHA_SEGUIMIENTO
FROM SEGUIMIENTOS
WHERE ID_PLAN_ACCION = [CODPA]
ORDER BY FECHA_SEGUIMIENTO desc;
This works because you are only returning one row.
EDIT:
If you have more codes, that you are looking at, you need a more complicated query. Here is an approach using where/not exists:
SELECT ID_PLAN_ACCION, ID_SEGUIMIENTO, FECHA_SEGUIMIENTO
FROM SEGUIMIENTOS s
WHERE not exists (select 1
from SEGUIMIENTOS s2
where s.ID_PLAN_ACCION = s2.ID_PLAN_ACCION and
s2.FECHA_SEGUIMIENTO > s.FECHA_SEGUIMIENTO
)
ORDER BY FECHA_SEGUIMIENTO desc;
You can read this as: "Get me all rows from SEGUIMIENTOS where there is no other row with the same ID_PLAN_ACCION that has a larger date". Is is another way of saying that the original row has the maximum date.