How to retrieve the last row of a table? - sql

How to retrieve the last row of a table which doesn't has any unique id like
select * from sample where id=(select max(id) from sample)

select TOP 1 * from sample order by whatever DESC
There must be some sort (ORDER BY) criteria to define the last row, otherwise your request makes no sense. For example, the last row based on AddedDateTime column in the product table
select TOP 1 * from product order by AddedDateTime DESC

Related

Getting MAX of a column and adding one more

I'm trying to make an SQL query that returns the greatest number from a column and its respective id.
For more information I have two columns ID and NUMBER. Both of them have 2 entries and I want to get the highest number with the ID next to it. This is what I tried but didn't success.
SELECT ID, MAX(NUMBER) AS MAXNUMB
FROM TABLE1
GROUP BY ID, MAXNUMB;
The problem I'm experiencing is that it just shows ALL the entries and if I add a "where" expression it just shows the same (all entries [ids+numbers]).
Pd.: Yes, I got what I wanted but only with one column (number) if I add another column (ID) to select it "brokes".
Try:
SELECT
ID,
A_NUMBER
FROM TABLE1
WHERE A_NUMBER = (
SELECT MAX(A_NUMBER)
FROM TABLE1);
Presuming you want the IDs* of the row with the highest number (and not, instead, the highest number for each ID -- if IDs were not unique in your table, for example).
* there may be more than one ID returned if there are two or more IDs with equal maximum numbers
you can try this
Select ID,maxNumber
From
(
SELECT
ID,
(Select Max(NUMBER) from Tmp where Id = t.Id) maxNumber
FROM
Tmp t
)T1
Group By ID,maxNumber
The query you posted has an illegal column name (number) and is group by the alias for the max value, which is illegal and also doesn't make sense; and you can't include the unaliased max() within the group-by either. So it's likely you're actually doing something like:
select id, max(numb) as maxnumb
from table1
group by id;
which will give one row per ID, with the maximum numb (which is the new name I've made up for your numeric column) for each ID. Or as you said you get "ALL the entries" you might have group by id, numb, which would show all rows from the table (unless there are duplicate combinations).
To get the maximum numb and the corresponding id you could group by id only, order by descending maxnumb, and then return the first row only:
select id, max(numb) as maxnumb
from table1
group by id
order by maxnumb desc
fetch first 1 row only
If there are two ID with the same maxnumb then you would only get one of them - and which one is indeterminate unless you modify the order by - but in that case you might prefer to use first 1 row with ties to see them all.
You could achieve the same thing with a subquery and analytic function to generating a ranking, and have the outer query return the highest-ranking row(s):
select id, numb as maxnumb
from (
select id, numb, dense_rank() over (order by numb desc) as rnk
from table1
)
where rnk = 1
You could also use keep to get the same result as first 1 row only:
select max(id) keep (dense_rank last order by numb) as id, max(numb) as maxnumb
from table1
fiddle

Selecting most recent rows in a SQL query

I want to join two tables, selecting the most recent rows for an ID value present in table 1.
i.e. For each ID value in table 1, only return the most recently added row for an ID value.
For example, table 1 looks something like this:
Columns: ID-value, date-added, other-information
row 1: ID_1, 21/2/2020-12:30, other_newer_information...
row 2: ID_1, 21/2/1990-12:30, other_older_information...
So if the same ID value is found twice in this table, only return the more recent entry, row 1 in the above case.
I then want to join these rows with information present in a second table.
e.g. table 2 looks something like this:
Columns: column-present-in-table-1, another-column-present-in-table-1, other-columns
row 1: some_data, some_more_data... additional data
row 2:- some_data, infor_2: some_more_data... additional data
etc
My sql query below works as expected for joining the two tables
but what I can't work out is how to only return the most recent rows from table 1 when duplicate ID values have been entered on multiple dates
Also not sure if the date filtering should occur as part of the SELECT or when first fetching data from table 1
From looking elsewhere in StackOverflow the suggestions are things like MAX(date_time) - but my understanding is that this will only return the maximum date time value, not the most recent row - correct me if I'm wrong.
My query looks something like this:
SELECT
id_1,
info_1,
info_2,
date_time,
info_3,
info_4,
max(info_3),
min(info_4)
FROM table_1
INNER JOIN table_2
ON table_1.info_1 = table_2.infor_1
AND table_1.info_2 = table_2.infor_2
WHERE id_1 in ("id1", "id2")
AND info_3 = "10"
GROUP BY id_1, info_1, info_2, info_3, info_4
ORDER BY id_1, id_2, date_time DESC
Other suggestions on StackOverflow: SELECT TOP id_1...min(info_4) (gives syntax error), ORDER BY id_1... date_time DESC LIMIT 1 (only returns one row - i.e. most recent date time).
ROW_NUMBER() OVER (PARTITION BY id, ORDER BY date_time) AS 'row_number' returns a row number, not the most recent row.
So if the same ID value is found twice in my table, only return the more recent entry, row 1 in the above case.
You can use row_number():
select t.*
from (select t.*,
row_number() over (partition by id order by date_time desc) as seqnum
from mytable t
) t
where seqnum = 1;
I really have no idea what your query has to do with your question. If your "table" is really the result of the query, then just use a CTE or subquery:
with t as (
<your query here>
)
<query with row_number here>

PostgresSQL: How to count up values in a row, then reset count when row value changes

So I have the table below, I want to alter the table to display the second table, where I count up the number of IDs, then reset the count as I come to a different ID value.
Current Table
Desired Table
Just use row_number():
select t.*, row_number() over(partition by id order by case_number) cnt
from mytable t

how to select the most recent records

Select id, name , max(modify_time)
from customer
group by id, name
but I get all records.
Order by modify_time desc and use row_number to number the row for id,name combination.Then select each combination with row_number = 1
select id,modify_time,name
from (
select id,modify_time,name,row_number() over(partition by id order by modify_time desc) as r_no
from customer
) a
where a.r_no=1
Ids are unique, which means grouping them by the id, will result in the same table.
My suggestion would be, to order the table by "modify_time" descending and limit the result to 1 (Maybe something like the following):
Select id, name modify_time from customer ORDER BY modify_time DESC limit 1
The reason you are getting the whole table as a result is because you are grouping by id AND name. That means every unique combination of id and name is returned. And since all names per id are different, the whole table is returned.
If you want the last modification per id (or name) you should only group by id (or name respectively).

Select last duplicate row with different id Oracle 11g

I have a table that look like this:
The problem is I need to get the last record with duplicates in the column "NRODENUNCIA".
You can use MAX(DENUNCIAID), along with GROUP BY... HAVING to find the duplicates and select the row with the largest DENUNCIAID:
SELECT MAX(DENUNCIAID), NRODENUNCIA, FECHAEMISION, ADUANA, MES, NOMBREESTADO
FROM YourTable
GROUP BY NRODENUNCIA, FECHAEMISION, ADUANA, MES, NOMBREESTADO
HAVING COUNT(1) > 1
This will only show rows that have at least one duplicate. If you want to see non-duplicate rows too, just remove the HAVING COUNT(1) > 1
There are a number of solutions for your problem. One is to use row_number.
Note that I've ordered by DENUNCIID in the OVER clause. This defines the "Last Record" as the one that has the largest DENUNCIID. If you want to define it differently you'd need to change the field that is being ordered.
with dupes as (
SELECT
ROW_NUMBER() OVER (Partition by NRODENUNCIA ORDER BY DENUNCIID DESC) RN,
*
FROM
YourTable
)
SELECT * FROM dupes where rn = 1
This only get's the last record per dupe.
If you want to only include records that have dupes then you change the where clause to
WHERE rn =1
and NRODENUNCIA in (select NRODENUNCIA from dupes where rn > 1)