How to extract the latest row - sql

I have a table like this:
Item Serial_No Grade Size Location Date
CQ35 A243911 4 36 A 20110127
CQ35 A243911 4 36 B 20110329
CQ35 A243911 4 36 C 20110330
CQ38 A244567 3 38 A 20110127
CQ35 A244567 3 38 B 20110128
CQ38 A244567 3 38 C 20110129
CQ35 A244567 3 38 D 20110130
CQ40 A244568 3 41 A 20110127
CQ40 A244568 3 41 B 20110129
CQ36 A244570 2 37 A 20110125
The expected results shd look like this using SQL:
Item Serial_No Grade Size Location Date
CQ35 A243911 4 36 C 20110330
CQ35 A244567 3 38 D 20110130
CQ40 A244568 3 41 B 20110129
CQ36 A244570 2 37 A 20110125
I'm trying to extract the latest row of each Serial No.
Thanks

UPDATE : with date
select *
from table as outertable
where date = (select max(date) from table where Serial_No = outertable.Serial_No)
The trick here is to do comparison in the range of Serial_No only, and the way to achieve this is with a Correlated Subquery as shown here.

This assumes that there is only one entry for each date and serial number.
SELECT MyTable.*
FROM MyTable
INNER JOIN (SELECT SerialNo, MAX(Date)
FROM MyTable
GROUP BY SerialNo) AS MyTableLatest ON MyTable.SerialNo = MyTableLatest.SerialNo
AND MyTable.Date = MyTableLatest.Date

Something like this:
SELECT *
FROM table
WHERE Date
IN (
SELECT MAX( Date )
FROM table
GROUP BY Serial_No
)

Related

update _ids values by sorted timestamp with sql

i have a few tables look like below (sqlite)
table a:
a_id (unique)
timestamp
21
123
2
178
33
101
7
221
4
115
table b:
b_id (unique)
a_id
data (no need to sort)
14
4
bb
3
2
dd
22
21
ee
6
7
xx
17
2
tt
11
33
qq
now i want to update these tables' _id according to the timestamp in a as follows:
table a:
a_id
timestamp
1
101
2
115
3
123
4
178
5
221
table b:
b_id
a_id
data
1
1
qq
2
2
bb
3
3
ee
4
4
dd
5
2
tt
6
5
xx
how can i do this easily with sql, without re inserting the data etc?
thanks
i used to create a dummy column with new and sorted ids by timestamp, then update other tables accordingly but it was inefficient and i have forgotten how i did it
update:
to simplify, i want to create a new column sort_id in table a, which holds the value according to the sorted timestamp, so
before:
table a
a_id (unique)
timestamp
21
123
2
178
33
101
7
221
4
115
after:
table a
a_id (unique)
timestamp
sort_id
21
123
3
2
178
4
33
101
1
7
221
5
4
115
2
so how can i fill the sort_id column according to the timestamp?
you want to query your table b data and sort it based on time stamp .
order of rows in a database is not guaranteed at all and it changes anytime after each insert/update, so you need to join two tables and sort based on timestamp column :
select b.*
from table_b b
left join table_a a
on a.a_id = b.a_id
order by a.timestamp
depending on your sqlite version you also can use update from :
update tableb
set sort_id = rn
from (select a_id , row_number() over (order by timestamp) as rn from tableA) tableA
where tableA.a_id = tableB.a_.id
Aftrer you've altered the table to add the new column...
WITH
sorted AS
(
SELECT
a_id,
ROW_NUMBER() OVER (ORDER BY timestamp) AS new_sort_id
FROM
table_a
)
UPDATE
table_a
SET
sort_id = sorted.new_sort_id
FROM
sorted
WHERE
table_a.a_id = sorted.a_id

Linking different ids through interactor

I want to link different ids through the common interactor. It is bit complex but i will try my best to frame the problem.
Here are the list of steps
1. Extract id from table A.
Table A
ID Interactor
1 30
2 40
Get the list of interactors corresponding to id from table B. for example,
select * from table B where id = 1
Table B
ID Interactors
1 30
1 32
1 33
1 36
1 38
1 39
Iterate through each interactor from the list and get the list of ids from table A.
Table A
ID Interactors
1 30
70 32
76 33
Null 36
89 38
75 39
2 45
2 40
2 43
4.Join these different ids so that when i select 1 i should get the below result.
Select * where id = 1
Result
ID Interactors
1 30
70 32
76 33
89 38
75 39
I want to achieve this using sql.
Try this:
select B.ID, B.Interactors
from A inner join B
where A.Interactors = B.Interactors
and A.ID = 1
From step 3 you have table A, and before that you have table B.
You can use simple inner join with some where condition to get your desired result.
Select Id, Interactors from
( select tableA.id, tableA.Interactors
from tableA
inner join tableB
on tableA.Interactors = tableB.Interactors
and tableA.Id is not null --- this is required since in your output record having NULL id correspond to tableA is not considered
) as db
where db.Id = 1 ---- you can apply any filter over there to get your desired result.

Re-Organize Access Table by converting Rows to Columns

I'm pretty new to access and SQL and need some help re-organizing a table. I have the following table (sorry for the table below - having trouble posting):
ID GroupID Distance Code Start_Finish
1 44 7 A S1
2 44 14 A F1
3 45 12 B S1
4 45 16 B F1
5 45 31 C S2
6 45 36 C F2
7 45 81 B S3
8 45 88 B F3
And need for the table to be transformed into:
GroupID Code Start_Distance Finish_Distance
44 A 7 14
45 B 12 16
45 C 31 36
45 B 81 88
try something like this
Select GroupID, Code, min(distance) as Start_distance, max(distance) as Finish_distance
from Table
group by GroupID, Code
If the min and max functions don't give you what you need, try it with First() and Last() instead.
Oops - just noticed you have 2 different entries in the output for GroupID 45 Code B - is that a requirement? With that data structure and requirement, the problem gets much more difficult.
Now I see the final column in the 1st table - I think that can be used to get the output you want:
Select GroupID, Code, mid(start_finish,2) as T, min(distance) as Start_distance, max(distance) as Finish_distance
from Table
group by GroupID, Code, T
You can use conditional aggregation for this.
select GroupID
, CODE
, max(case when Left(Start_Finish, 1) = 'S' then Distance end) as Start_Distance
, max(case when Left(Start_Finish, 1) = 'F' then Distance end) as Finish_Distance
from SomeTable
group by GroupID
, CODE

how to Get only the rows which's D column hold nearest lowest number to the C column?

------------------------------------------
ID Name C D
------------------------------------------
1 AK-47 10 5
2 RPG 10 20
3 Mp5 20 15
4 Sniper 20 18
5 Tank 90 80
6 Space12 90 20
7 Rifle 90 110
8 Knife 90 85
Consider 1,2 ; 3,4 ; 5,6,7,8 are as separate groups
So i need to get the row group wise that which's D column holds the nearest lower number to the C column
So the Expected Result is :
------------------------------------------
ID Name C D
------------------------------------------
1 AK-47 10 5
4 Sniper 20 18
8 Knife 90 85
How can I achieve this ?
select t1.*
from your_table t1
join
(
select c, min(abs(c-d)) as near
from your_table
group by c
) t2 on t1.c = t2.c and abs(t1.c-t1.d) = t2.near
Here is the syntax for another way of doing this. This uses a cte and will only hit the base table once.
with MySortedData as
(
select ID, Name, C, D, ROW_NUMBER() over(PARTITION BY C order by ABS(C - D)) as RowNum
from Something
)
select *
from MySortedData
where RowNum = 1

Database Query Help required in MySQL

I am looking for help in writing a query of retrieving the values from 2 tables in MySQL.
The scenario is
Table A
ID Name Marks
===================
23 John 67
45 Mark 45
12 Ram 87
Table B has the following Structure
ID Name Evaluation Marks
==============================
45 Mark 34
78 Chris 09
98 Nancy 10
23 John 12
I am trying to write a query, where if I execute the following query
Select "SOMETHING" from Table A where Id=45
I should get Marks Column as 45+34=79, which should fetch and sum from the both the Tables A and Table B.
If I execute the query with the Id=12.
Since the Id=12, does not exists in the Table B, I should get the Marks as 87.
What would a query for the above?
I assume that the id occurs only once in your tables table a, but could be missing in both. If it always exists in table a, you can use a LEFT JOIN instead of the UNION.
SELECT COALESCE(SUM(marks), 0)
FROM
(
SELECT marks FROM a WHERE id = 45
UNION ALL
SELECT SUM(evaluation_marks) AS marks FROM b WHERE id = 45
) x
Edit
If you have all users in table a, then use
SELECT a.marks + COALESCE( SUM( b.evaluation_marks ), 0 )
FROM a
LEFT OUTER JOIN b ON ( b.id = a.id )
WHERE a.id = 45
GROUP BY a.id, a.marks
You should consider changing your table model though. Why do you store name and id twice? Can't you do it like that:
id name marks evaluation marks
=======================================
12 Ram 87 0
23 John 67 12
45 Mark 45 34
78 Chris 0 9
98 Nancy 0 10