Query to fetch max records from a table - sql

I am having a table name batch_log whose structure is as below
batch_id run_count start_date end_date
1 4 03/12/2014 03/12/2014
1 3 02/12/2014 02/12/2014
1 2 01/12/2014 01/12/2014
1 1 30/11/2014 30/11/2014
2 5 03/12/2014 03/12/2014
2 4 02/12/2014 02/12/2014
2 3 01/12/2014 01/12/2014
2 2 30/11/2014 30/11/2014
2 1 29/11/2014 29/11/2014
3 3 02/12/2014 02/12/2014
3 2 01/12/2014 01/12/2014
3 1 30/11/2014 30/11/2014
I need to fetch rows for all the batch_id with max run_count.
result of the query should be :
batch_id run_count start_date end_date
1 4 03/12/2014 03/12/2014
2 5 03/12/2014 03/12/2014
3 3 02/12/2014 02/12/2014
I tried many options using, group by batch_id and run_count but not able to get the correct result
select a.* from batch_log a,batch_log b
where a.batch_id =b.batch_id
and a.run_count=b.run_count
and a.run_count in (select max(run_count) from batch_log
group by batch_id ) order by a.batch_id
Plese help

select *
from(
select a.*, max(run_count) over (partition by batch_id) max_run_count
from batch_log a)
where run_count=max_run_count;

This should also work:
SELECT * FROM batch_log b1
WHERE b1.run_count = (SELECT max(b2.run_count)
FROM batch_log b2
WHERE b2.batch_id = b1.batch_id
GROUP BY b2.batch_id)

You can do it by this query :
select *
from batch_log a
inner join (
select b.batch_id , max(run_count) as run_count
from batch_log b
group by b.batch_id
) c on a.batch_id = c.batch_id and a.run_count = c.run_count
Hope it helps

Answer given by Arion is looking perfect to me. You can modify to this as per below to achieve your exact requirement
SELECT batch_id,run_count,start_date,end_date
FROM
(
SELECT
ROW_NUMBER() OVER(PARTITION BY batch_id ORDER BY run_count DESC) AS RowNbr,
batch_log.*
FROM
batch_log
) as batch
WHERE
batch.RowNbr=1

Related

Select all rows if only one matches

I have two tables: FEATURE and FEATURE_DETAILS. Relation is one(FEATURE) to many(FEATURE_DETAILS).
feature_details_id | feature_id
1 1
1 2
1 4
2 1
2 2
2 4
2 5
3 1
3 5
How could I select all rows which contains e.g. 5?
feature_details_id | feature_id
2 1
2 2
2 4
2 5
3 1
3 5
first get the list of feature_deatails_id for which feature_id is 5, then pass the feature_deatails_id to FEATURE_DETAILS table to get the result
Try something like this
select *
from FEATURE_DETAILS
where feature_deatails_id in(
select feature_deatails_id from FEATURE_DETAILS where feature_id = 5)
or use Max()Over() Window function(preferred approach)
select * from
(
select max(case when feature_id = 5 then 1 else 0 end)over(partition by feature_deatails_id) as cnt,
feature_deatails_id,feature_id
from FEATURE_DETAILS
)s
Where cnt = 1
SELECT * FROM FEATURE_DETAILS WHERE feature_details_id IN (
SELECT feature_details_id from FEATURE_DETAILS WHERE feature_id=5
)

Oracle SQL with Join and count

I would like to join two tables, A and B, with a count function.
Table A has the followings:
SQL> select a.book_id, count(a.book_id)
from
a
group by a.book_id ;
BOOK_ID COUNT(A.BOOK_ID)
--------- ----------------
1 2
2 2
3 2
4 2
5 2
6 3
and table B has the followings:
SQL> select b.book_id, count(b.book_id)
from
b
group by b.book_id ;
BOOK_ID COUNT(B.BOOK_ID)
--------- ----------------
6 2
So I would like to have a query which gives me the following result:
BOOK_ID COUNT(A.BOOK_ID) COUNT(B.BOOK_ID)
--------- ---------------- ----------------
1 2 0
2 2 0
3 2 0
4 2 0
5 2 0
6 3 2
I tried this :
SQL> select b.book_id, count(b.book_id),a.book_id, count(a.book_id)
from
b , a
where
b.book_id(+) = a.book_id
group by b.book_id, a.book_id ;
but the results were like this :
BOOK_ID COUNT(B.BOOK_ID) BOOK_ID COUNT(A.BOOK_ID)
--------- ---------------- --------- ----------------
0 1 2
0 2 2
0 3 2
0 4 2
0 5 2
6 6 6 6
Something like this perhaps:
select a.book_id as id_a,
(select count(1) from a a2 where a2.book_id = a.book_id) as count_a,
b.book_id as id_b,
(select count(1) from b b2 where b2.book_id = a.book_id) as count_b
from a
left join b on b.book_id = a.book_id
group by a.book_id;
Another way to do it:
WITH total_list AS (
SELECT a.Book_id, 'a' AS a_cnt, NULL AS b_cnt FROM a
UNION ALL
SELECT b.Book_id, NULL, 'b')
SELECT Book_id, COUNT(a_cnt) AS a_total, COUNT(b_cnt) AS b_total
GROUP BY Book_id
ORDER BY Book_id
What this does is it uses a subquery to union together both of your book tables and attaches a flag to it to signify if it belonged to table a or table b. From there, I just selected from the subquery.

SQL Server: Join 2 tables, preferring results from one table where there is a conflict

I have tables that looks like this:-
tblConsuptionsFromA
id meter date total
1 1 03/01/2014 100.1
2 1 04/01/2014 184.1
3 1 05/01/2014 134.1
4 1 06/01/2014 132.4
5 1 07/01/2014 126.1
6 1 08/01/2014 190.1
and...
tblConsuptionsFromB
id meter date total
1 1 01/01/2014 164.1
2 1 02/01/2014 133.1
3 1 03/01/2014 136.1
4 1 04/01/2014 125.1
5 1 05/01/2014 190.1
6 1 06/01/2014 103.1
7 1 07/01/2014 164.1
8 1 08/01/2014 133.1
9 1 09/01/2014 136.1
10 1 10/01/2014 125.1
11 1 11/01/2014 190.1
I need to join these two tables, but if there is an entry for the same day in both table... only take the result from tblConsumptionsFromA.
So the result would be:-
id source_id meter from date total
1 1 1 B 01/01/2014 164.1
2 2 1 B 02/01/2014 133.1
3 1 1 A 03/01/2014 100.1
4 2 1 A 04/01/2014 184.1
5 3 1 A 05/01/2014 134.1
6 4 1 A 06/01/2014 132.4
7 5 1 A 07/01/2014 126.1
8 6 1 A 08/01/2014 190.1
9 9 1 B 09/01/2014 136.1
10 10 1 B 10/01/2014 125.1
11 11 1 B 11/01/2014 190.1
This is beyond me, so if someone can solve... I will be very impressed.
Here's one way to do it:
SELECT
COALESCE(a.source_id,b.source_id) as source_id,
COALESCE(a.meter,b.meter) as meter,
COALESCE(a.[from],b.[from]) as [from],
COALESCE(a.[date],b.[date]) as [date],
COALESCE(a.total,b.total)
FROM (select source_id,meter,'b' as [from],[date],total
from tblConsuptionsFromB) b
left join
(select source_id,meter,'a' as [from],[date],total
from tblConsuptionsFromA) a
on
a.meter = b.meter and
a.[date] = b.[date]
Unfortunately, there's no shorthand like COALESCE(a.*,b.*) to apply the COALESCE to all columns
The UNION operator is used to combine the result-set of two or more SELECT statements.
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;
The document of UNION is here:
http://www.w3schools.com/sql/sql_union.asp
And ROW_NUMBER() returns the sequential number of a row within a partition of a result set, starting at 1 for the first row in each partition.
ROW_NUMBER ( )
OVER ( [ PARTITION BY value_expression , ... [ n ] ] order_by_clause )
The document of ROW_NUMBER() is here:
http://technet.microsoft.com/en-us/library/ms186734.aspx
The following SQL statement uses UNION to select all records from the "tblConsuptionsFromA" and part of records from "tblConsuptionsFromB" tables.
SELECT ROW_NUMBER() OVER(ORDER BY DATE ASC) AS 'id',
id AS 'source_id',meter, date,t AS 'from',total
FROM(
SELECT id,meter, date, 'A' AS t, total FROM tblConsuptionsFromA
UNION
SELECT id,meter, date, 'B' AS t,total FROM tblConsuptionsFromB
WHERE NOT date IN (SELECT date FROM tblConsuptionsFromA)
) AS C;
Hope this helps.
select ta.id, tb.id, ta.meter,
if(ta.date is null, 'B', 'A') as from,
if(ta.date is null, tb.date, ta.date) as date,
if(ta.date is null, tb.total, ta.total) as total
from tblConsuptionsFromA ta
full join tblConsuptionsFromB tb on ta.date=tb.date
You would need to do a Union of the 2 tables, and exclude records from tabletblConsuptionsFromB which are present in tblConsuptionsFromA, something like:
Select Id, Source_ID, meter, 'A' From, Date, Total
FROM tblConsuptionsFromA
Union All
Select Id, Source_ID, meter, 'B' From, Date, Total
FROM tblConsuptionsFromB
Where Date NOT EXISTS (Select Date from tblConsuptionsFromA)

Query Two Different Table that have same field item

I have two table
Table_A
ID PostId Item Stock Price
1 1 A 30 10
2 1 B 40 20
3 2 A 50 5
4 3 A 50 25
Table_B
ID PostId Item_ID Sold Price
1 1 1 2 20
2 1 2 2 40
3 1 1 1 10
4 2 3 3 15
5 2 3 1 5
I want to queries from above two table that have same 'PostID' and COUNT and SUM some field group by 'PostID', expected output would be like this
Output
ID PostId Total Item Total Stock Total Buyer(s) Total Sold Total Price
1 1 2 70 3 5 70
I've try to JOIN it, but result still miss calculate
SELECT Table_A.PostId AS PostId, COUNT(Table_A.Item) AS Total_Item, SUM(Table_A.stock) AS Total_Stock, COUNT(Table_B.Item_ID) AS total_buyer, SUM( Table_B.Sold ) AS TotalSold, SUM( Table_B.Price ) AS Total_Price
FROM Table_A
LEFT JOIN Table_B
ON Table_A.PostId = Table_B.PostId
WHERE Table_A.PostId = '1'
GROUP BY Table_A.PostId
LIMIT 0 , 30
Any suggestion for this query problem?? Thank you
SELECT Table_B.PostId AS PostId,
MIN(Table_A.Total_Item) AS Total_Item,
MIN(Table_A.Total_Stock) AS Total_Stock,
COUNT(Table_B.Item_ID) AS total_buyer,
SUM( Table_B.Sold ) AS TotalSold,
SUM( Table_B.Price ) AS Total_Price
FROM Table_B
LEFT JOIN
(
SELECT PostId,
COUNT(Item) AS Total_Item,
SUM(stock) AS Total_Stock
FROM
Table_A
GROUP BY PostId
) Table_A
ON Table_B.PostId=Table_A.PostId
WHERE Table_B.PostId = '1'
GROUP BY Table_B.PostId
LIMIT 0 , 30

Select and aggregate last records base on order

I have different versions of the charges in a table. I want to grab and sum the last charge grouped by Type.
So I want to add 9.87, 9.63, 1.65.
I want the Parent ID , sum(9.87 + 9.63 + 1.65) as the results of this query.
We use MSSQL
ID ORDER CHARGES TYPE PARENT ID
1 1 6.45 1 1
2 2 1.25 1 1
3 3 9.87 1 1
4 1 6.54 2 1
5 2 5.64 2 1
6 3 0.84 2 1
7 4 9.63 2 1
8 1 7.33 3 1
9 2 5.65 3 1
10 3 8.65 3 1
11 4 5.14 3 1
12 5 1.65 3 1
WITH recordsList
AS
(
SELECT Type, Charges,
ROW_NUMBER() OVER (PArtition BY TYPE
ORDER BY [ORDER] DESC) rn
FROM tableName
)
SELECT SUM(Charges) totalCharge
FROM recordsLIst
WHERE rn = 1
SQLFiddle Demo
Use row_number() to identify the rows to be summed, and then sum them:
select SUM(charges)
from (select t.*,
ROW_NUMBER() over (PARTITION by type order by id desc) as seqnum
from t
) t
where seqnum = 1
Alternatively you could use a window aggregate MAX():
SELECT SUM(Charges)
FROM (
SELECT
[ORDER],
Charges,
MaxOrder = MAX([ORDER]) OVER (PARTITION BY [TYPE])
FROM atable
) s
WHERE [ORDER] = MaxOrder
;
SELECT t.PARENT_ID, SUM(t.CHARGES)
FROM dbo.test73 t
WHERE EXISTS (
SELECT 1
FROM dbo.test73
WHERE [TYPE] = t.[TYPE]
HAVING MAX([ORDER]) = t.[ORDER]
)
GROUP BY t.PARENT_ID
Demo on SQLFiddle