Select group with maximum value of aggregate function - sql

I have this query
select dca_sif, maxupp
from (select d.sifra dca_sif , sum(col1) as maxup
from tableD d join tablev v on d.id=v.d_id
join tableT t on v.id=t.v_id
group by d.sif
order by maxup desc
)
where rownum=1;
This returns first value, but If I have more groups with same maxup, how can I return all of them?
If I delete rownum=1, it returns all groups and coresponding maxup.
I want to return max(sum(col1)) but this cause error. Database is oracle.

You can try somthing like this:-
SELECT dca_sif, MAX(maxup)
FROM (SELECT d.sifra dca_sif , SUM(col1) AS maxup
FROM tableD d JOIN tablev v ON d.id=v.d_id
JOIN tableT t ON v.id=t.v_id
GROUP BY d.sif
ORDER BY maxup DESC
)
WHERE ROWNUM=1
GROUP BY dca_sif;
This might be helpful to you.

You can combine your select with the same select, but without the rownum limitation. Than join on the max id. There are many tables in your statement, so it is difficult to test for me, but this should work:
SELECT count(qry2.dcasif) || ' groups', sum( qry2.maxup2)
FROM ( SELECT dca_sif, MAX (maxup) AS maxup1
FROM ( SELECT d.sifra dca_sif, SUM (col1) AS maxup
FROM tabled d
JOIN tablev v ON d.id = v.d_id
JOIN tablet t ON v.id = t.v_id
GROUP BY d.sif
ORDER BY maxup DESC)
WHERE ROWNUM = 1
GROUP BY dca_sif) qry1
, ( SELECT dca_sif, MAX (maxup) AS maxup2
FROM ( SELECT d.sifra dca_sif, SUM (col1) AS maxup
FROM tabled d
JOIN tablev v ON d.id = v.d_id
JOIN tablet t ON v.id = t.v_id
GROUP BY d.sif
ORDER BY maxup DESC)
GROUP BY dca_sif) qry2
WHERE qry1.maxup1 = qry2.maxup2

SELECT dca_sif, maxup
FROM
(SELECT a.*,rank() over(order by maxup desc)as Rank
FROM (SELECT d.sifra dca_sif , SUM(col1) AS maxup
FROM tableD d JOIN tablev v ON d.id=v.d_id
JOIN tableT t ON v.id=t.v_id
GROUP BY d.sif
)a)
WHERE Rank=1

Related

INNER JOIN with IN

I want to combinate the following function with a table for many numbers(here "400") in an other table in Access with the join function.
SELECT tblData.ID,tblData.Data,(
SELECT TOP 1 d.Data
FROM tblData d
WHERE d.Data **< 400**
AND d.ID <= tblData.ID
ORDER BY d.ID DESC
) AS X
FROM tblData;
The join function is for arrays.
But you can join two tables, perhaps like this:
SELECT tblData.ID,tblData.Data,(
SELECT TOP 1 d.Data
FROM tblData d
INNER JOIN OtherTable
ON d.Data = OtherTable.Data
WHERE d.ID <= tblData.ID
ORDER BY d.ID DESC
) AS X
FROM tblData;

Find the first N nearest points in Bigquery

To find the nearest point and its distance in Bigquery I am using this query
WITH table_a AS (
SELECT id, geom
FROM bqtable
), table_b AS (
SELECT id, geom
FROM bqtable
)
SELECT AS VALUE ARRAY_AGG(STRUCT<id_a STRING,id_b STRING, dist FLOAT64>(a.id,b.id,ST_DISTANCE(a.geom, b.geom)) ORDER BY ST_DISTANCE(a.geom, b.geom) LIMIT 1)[OFFSET(0)]
FROM (SELECT id, geom FROM table_a) a
CROSS JOIN (SELECT id, geom FROM table_b) b
WHERE a.id <> b.id
GROUP BY a.id
How can I modify this query to find the nearest 10 points and their distances?
Thanks!
One method uses ORDER BY, LIMIT, and UNNEST(). Using your approach:
SELECT AS VALUE s
FROM (SELECT ARRAY_AGG(STRUCT<id_a STRING,id_b STRING, dist FLOAT64>(a.id, b.id, ST_DISTANCE(a.geom, b.geom))
ORDER BY ST_DISTANCE(a.geom, b.geom)
LIMIT 10
) as ar
FROM (SELECT id, geom FROM table_a) a CROSS JOIN
(SELECT id, geom FROM table_b) b
WHERE a.id <> b.id
GROUP BY a.id
) ab CROSS JOIN
UNNEST(ab.ar) s;
A simpler method would be
select id_a, id_b, ST_DISTANCE(a.geom, b.geom) as dist
from table_a a cross join
table_b b
where a.id <> b.id
qualify row_number() over (partition by id_a order by dist) <= 10;

Removing duplicate values from a column in SQL

I have two tables A (group_id, id, subject) and B (id, date). Below is the joint table of tables A and B on id. I have tried using distinct and partition to remove the duplicates in group_id(field) only, but no luck:
My code:
select
a.group_id, a.id, a.subject, b.date
from
A a
inner join
(select
b.*,
row_number() over (partition by group_id order by date asc) as seqnum
from
B b) b on a.id = b.id and seqnum = 1
order by
date desc;
I got this error when I ran the code:
Partitioning can not be used stand-alone in query near 'partition by group_id order by date asc) as seqnum from B' at line 1
This is my expected result:
Thank you in advance!
It looks like you want the earliest date for each row in the table you show. Your question mentions two tables, but you only show one.
I recommend a correlated subquery in most databases:
select b.*
from b
where b.date = (select min(b2.date)
from b b2
where b2.group_id = b.group_id
);
I see. You need to join first and then use row_number():
select ab.*
from (select a.group_id, a.id, a.subject, b.date,
row_number() over (partition by a.group_id order by b.date) as seqnum
from A a join
B b
on a.id = b.id
) ab
where seqnum = 1
order by date desc;
You are almost there. But the column that you try to use to partition (ie group_id) comes from table a, which is not available in the subquery.
You would need to JOIN and assign the row number in a subquery, and then filter in the outer query.
select *
from (
select
a.group_id,
a.id,
a.subject,
b.date,
row_number() over (partition by a.group_id order by b.date asc) as seqnum
from a
inner join b on ON a.id = b.id
)
where seqnum = 1
ORDER BY date desc;
Another way to achieve your goal though it may not be the efficient one
SELECT
A.group_id, A.id, B.Date, A.subject
FROM A
INNER JOIN B
ON A.Id = B.Id
INNER JOIN
(
SELECT
A.Group_id, MIN(B.Date) AS Date
FROM A
INNER JOIN B
ON A.Id = B.Id
GROUP BY A.group_id
) AS supportTable
ON A.group_id = supportTable.group_id
AND B.Date = supportTable.Date

Syntax Error on Distinct inside a Join in SQL Server

I have a query and I need to display distinct values from a join. I have this kind of SQL query
select
a.member_id, b.registered_time
from
b
left join
(select distinct a.member_id from a) on b.mirror_id = a.mirror_id
order by
b.registered_time desc;
But this query returns me a syntax error
Incorrect syntax near the keyword 'on'
How can I fix that?
I also tried doing this query but it returns an error
Invalid column name 'mirror_id'
Code:
select
a.member_id, b.registered_time
from
b
left join
(select distinct a.member_id from a) a on b.mirror_id = a.mirror_id
order by
b.registered_time desc;
I also tried doing this kind
select
a.member_id, b.registered_time
from
b
left join
(select distinct a.member_id from a) AP on b.mirror_id = a.mirror_id
order by
b.registered_time desc;
but it returns an error that multipart identifier couldn't be bound
I have these kind of result from my join:
For example I have these two tables
Table a
Table 2
But I need to display only one member_id with the latest registered_time
Original (reformatted):
select a.member_id, b.registered_time
from b
left join (select distinct a.member_id from a)
on b.mirror_id = a.mirror_id
order by b.registered_time desc;
Step 1, place the alias AFTER the subquery:
select a.member_id, b.registered_time
from b
left join (select distinct a.member_id from a) a
------------------------------------------------^
on b.mirror_id = a.mirror_id
order by b.registered_time desc;
Step 2, INCLUDE the column mirror_id inside the subquery
select a.member_id, b.registered_time
from b
left join (select distinct a.member_id, mirror_id from a) a
---------------------------------------^^^^^^^^^^^
on b.mirror_id = a.mirror_id
order by b.registered_time desc;
At this point the query should work, but I cannot tell if it is functionally what you want unless you provide sample data and expected result.
EDIT (2)
a simple GROUP BY may be used to arrive at a max date per member:
SELECT
a.member_id
, max(b.registered_time) registered_time
FROM a
INNER JOIN b ON a.mirror_id = b.mirror_id
GROUP BY
a.member_id
If you need whole rows from table a, then the row_number() approach is better:
SELECT d.*
FROM (
SELECT
a.*
, b.registered_time
, row_number() over(partition by a.member_id order by b.registered_time DESC) rn
FROM a
INNER JOIN b ON a.mirror_id = b.mirror_id
) d
WHERE d.rn = 1
You need a table alias:
select a.member_id, b.registered_time
from b left join
(select distinct a.member_id
from a
) a
-------^
on b.mirror_id = a.mirror_id
order by b.registered_time desc;
EDIT:
Well, you need the mirror_id to do the join. Why do you need the distinct? In any case, you can try:
select a.member_id, b.registered_time
from b left join
(select a.mirror_id, min(a.member_id) as member_id
from a
group by a.mirror_id
) a
on b.mirror_id = a.mirror_id
order by b.registered_time desc;

Add row number to this T-SQL query

How can I add ROW numbers to this query result?
SELECT DISTINCT
VehicleSpecs.SubmittedById,
COUNT(VehicleSpecs.SubmittedById) AS NumCars,
aspnet_Users.UserName
FROM
VehicleSpecs
INNER JOIN aspnet_Users ON VehicleSpecs.SubmittedById = aspnet_Users.UserId
WHERE
(LEN(VehicleSpecs.SubmittedById) > 0)
GROUP BY
VehicleSpecs.SubmittedById,
aspnet_Users.UserName
ORDER BY
NumCars DESC
Add: ROW_NUMBER() OVER (ORDER BY NumCars)
EDIT:
WITH t1 AS
( SELECT DISTINCT
VehicleSpecs.SubmittedById ,
COUNT(VehicleSpecs.SubmittedById) AS NumCars ,
aspnet_Users.UserName
FROM VehicleSpecs
INNER JOIN aspnet_Users ON VehicleSpecs.SubmittedById = aspnet_Users.UserId
WHERE ( LEN(VehicleSpecs.SubmittedById) > 0 )
GROUP BY VehicleSpecs.SubmittedById ,
aspnet_Users.UserName
)
SELECT ROW_NUMBER() OVER ( ORDER BY NumCars ), *
FROM t1
ORDER BY NumCars
Wrap you entire query in a sub query and add row_number in the outer query.
select *, row_number() over(order by (select 0)) as rn
from
(
select distinct -- your columns
from YourTable
) as T
order by NumCars desc