This question already has an answer here:
SQL Max(date) without group by
(1 answer)
Closed 2 years ago.
I need to help to get a max value for each id. Simple table is just shown below,
ID Value
---------------
111 150
112 110
111 100
113 120
115 130
111 180
112 190
What I want too see in the output:
ID Value
---------------
111 180
112 190
111 180
113 120
115 130
111 180
112 190
I do not want to group by each id, I want all of them in the output.
I think you want window functions:
select t.*, max(value) over (partition by id) as max_id
from t;
This answers the question. I'm not sure what the sample data has to do with the question.
You could also correlated subquery in the SELECT list:
SELECT
id,
(SELECT
max(value)
FROM
tbl t2
WHERE
t2.id = t1.id) AS value
FROM
tbl t1
If you do not want to use the MAX function at all then you can use the NOT EXISTS as follows:
SELECT Y.ID, R.VALUE
FROM YOUR_TABLE Y
JOIN ( SELECT DISTINCT ID, VALUE
FROM YOUR_TABLE T
WHERE NOT EXISTS ( SELECT 1
FROM YOUR_TABLE TT
WHERE TT.ID = T.ID
AND TT.VALUE > T.VALUE
)
) R ON Y.ID = R.ID
Related
I am working on DB2.
There are duplicate rows in the table. I need to extract data where there is different value in 2nd column for same value in 1st column.
there are column other than these in table but only need to consider these.
for example:
NBR
SE_NBR
123
56
123
56
123
56
248
75
248
75
To extract
NBR
SE_NBR
456
12
456
34
456
11
135
77
135
88
here is one way using window function:
select * from
(
select *, min(SE_NBR) over (partition by NBR) minnbr, max(SE_NBR) over (partition by NBR) maxnbr
from nbrtable
) t
where minnbr <> maxnbr
if window function is not supported:
select * from tableName t1
where exists (
select 1 from tablename t2
where t1.NBR = t2.NBR
group by t2.nbr
having count(distinct SE_NBR) > 1
)
db<>fiddle here
You can do:
select *
from t
where nbr in (
select nbr from t group by nbr having count(distinct se_nbr) > 1
)
I have a simple table like this
station num tim
-------------------------
1 150 10
1 200 222
1 100 5000
1 200 555
2 100 500
2 120 200
3 1 2
The desired output is like this:
station num tim
---------------------
1 200 555
2 120 200
3 1 2
but I can't use ROW_NUMBER() because query needs to be executed in MS Access SQL.
Can anyone help me?
Try using subquery
select A.* from
(
select station,num, max(tim) as mtim
from tablename
group by station,num
)A where num in (select max(num) from tablename B where A.station=B.station)
You can try this also:
select t2.station,t1.num as num,max(t2.tim) tim from (select max(num) num
from tablename group by station) t1
join tablename on t1.num = t2.num group by t1.num,t2.station
You can do this with two exists queries:
select s.*
from simple as s
where s.num = (select max(s2.num)
from simple as s2
where s2.station = s.station
) and
s.tim = (select max(s2.tim)
from simple as s2
where s2.station = s.station and s2.num = s.num
) ;
Because this doesn't do aggregation (overall) and can make use of an index on (station, num, tim), it is probably the best performing approach.
How to get the max value order of each customer ?
select num, max(sum(paid*quantity))
from orders join
pizza
using (order#)
group by customer#;
table
num orderN price
-------- --- -------
1 109 30
1 118 25
3 101 30
3 115 27
4 107 23
5 100 17
5 129 16
output req-
num Pnum price
-------- --- -------
1 109 30
3 101 30
4 107 23
5 100 17
You want to select the record having the highest price in each group of nums.
If your RDBMS supports window functions, that's straight forward with ROW_NUMBER() :
SELECT num, pnum, price
FROM (
SELECT t.*, ROW_NUMBER OVER(PARTITION BY num ORDER BY price DESC) rn
FROM mytable t
) x
WHERE rn = 1
Else, you can take the following approach, that uses a NOT EXISTS condition with a correlated subquery to ensure that the record being joined in the one with the highest price for the current num :
SELECT num, pnum, price
FROM mytable t
WHERE NOT EXISTS (
SELECT 1 FROM mytable t1 WHERE t1.num = t.num AND t1.price > t.price
)
I could need some help with a SQL statement. So I have the table "cont" which looks like that:
cont_id name weight
----------- ---------- -----------
1 1 10
2 1 20
3 2 40
4 2 15
5 2 20
6 3 15
7 3 40
8 4 60
9 5 10
10 6 5
I then summed up the weight column and grouped it by the name:
name wsum
---------- -----------
2 75
4 60
3 55
1 30
5 10
6 5
And the result should have a accumulated column and should look like that:
name wsum acc_wsum
---------- ----------- ------------
2 75 75
4 60 135
3 55 190
1 30 220
5 10 230
6 5 235
But I didn't manage to get the last statement working..
edit: this Statement did it (thanks Gordon)
select t.*,
(select sum(wsum) from (select name, SUM(weight) wsum
from cont
group by name)
t2 where t2.wsum > t.wsum or (t2.wsum = t.wsum and t2.name <= t.name)) as acc_wsum
from (select name, SUM(weight) wsum
from cont
group by name) t
order by wsum desc
So, the best way to do this is using cumulative sum:
select t.*,
sum(wsum) over (order by wsum desc) as acc_wsum
from (<your summarized query>) t
The order by clause makes this cumulative.
If you don't have that capability (in SQL Server 2012 and Oracle), a correlated subquery is an easy way to do it, assuming the summed weights are distinct values:
select t.*,
(select sum(wsum) from (<your summarized query>) t2 where t2.wsum >= t.wsum) as acc_wsum
from (<your summarized query>) t
This should work in all dialects of SQL. To work with situations where the accumulated weights might have duplicates:
select t.*,
(select sum(wsum) from (<your summarized query>) t2 where t2.wsum > t.wsum or (t2.wsum = t.wsum and t2.name <= t.name) as acc_wsum
from (<your summarized query>) t
try this
;WITH CTE
AS
(
SELECT *,
ROW_NUMBER() OVER(ORDER BY wsum) rownum
FROM #table1
)
SELECT
c1.name,
c1.wsum,
acc_wsum= (SELECT SUM(c2.wsum)
FROM cte c2
WHERE c2.rownum <= c1.rownum)
FROM CTE c1;
or you can join instead of using subquery
;WITH CTE
AS
(
SELECT *,
ROW_NUMBER() OVER(ORDER BY usercount) rownum
FROM #table1
)
SELECT
c1.name,
c1.wsum,
acc_wsum= SUM(c2.wsum)
FROM CTE c1
INNER JOIN CTE c2 ON c2.rownum <= c1.rownum
GROUP BY c1.name, c1.wsum;
I have a table with 2 columns ID, ID_PROJ_CSR
The content of that table is:
ID ID_PROJ_CSR
------------------
747 222 <
785 102
786 222 <
787 223
788 224
I want to select the ID, but if any value from ID_PROJ_CSR is a duplicate, I need to select any ID of the rows that contains that duplicate value (in that example, select ID 747 OR 786
I try:
SELECT * FROM my_table tab
WHERE tab.id_proj_csr = (SELECT TOP 1 id_proj_csr
FROM my_table mt
WHERE mt.id_proj_csr = tab.id_proj_csr)
You need to GROUP BY:
SELECT MAX(ID) as [ID], ID_PROJ_CSR
FROM my_table
GROUP BY ID_PROJ_CSR
Here's the case of omitting anything that has a duplicate value, so you'll only get rows that don't have duplicates:
SELECT *
FROM my_table
GROUP BY ID_PROJ_CSR
HAVING count(ID_PROJ_CSR) = 1;