This question already has answers here:
Get top 1 row of each group
(19 answers)
Closed 6 months ago.
I need to select rows that are distinct by number and are the oldest date.
I saw this post: SQL Select Distinct column and latest date
But it doesn't work in my case, because I need to select all the columns, not just the 2 that are used in the clause.
So I get this error:
it is not contained in either an aggregate function or the GROUP BY clause` error.
Is there a way to choose all the columns, and in case there are rows with same date, consider the older one as the one with the lower id?
sample data:
id name number date
1 foo 1111 06-11-2022
2 bar 2222 01-12-2022
3 baz 3333 12-30-2022
4 foobar 1111 02-01-2022
this is the query I tried:
SELECT id, name, number, MIN(date) as date
FROM my_table
GROUP BY number
using Microsoft SQL
When you are using GROUP BY aggregate function, you can only use the aggregated columns in your SELECT list. You can achieve your expected output in several ways, Here is one using windowed aggregate function :
select T.*
from (select *,
row_number() over (partition by number order by [date], id) as sn
from my_table
) T
where sn = 1;
SQL here
Related
I have a table with various SKU in totes.
The table is totecontents with below columns:
ToteID
SKU
Each Tote can contain a maximum of 6 SKUs. (programmatically constrained)
select toteid, count(*) as qtypertote
from totecontents
group by toteid;
gives me a list of totes with the number of skus in each.
I now want to get to a table with following result
SkuCount Occurences where each row would have the ordinal value (1 through 6 ) and then the number of occurences of that value.
My efforts included the following approach
select count(*)
from
( select toteid, count(*) as qtypertote
from totecontents
group by toteid)
group by qtypertote;
Stung by the comments I performed more research. This works:
SELECT CountOfskus, COUNT(1) groupedCount
FROM
( SELECT COUNT(*) as countofskus, toteid
FROM totecontents
Group By toteid
) MyTable
GROUP BY countofskus;
This question already has answers here:
how to select max(column) and a column in the same request teradata
(3 answers)
Closed 8 months ago.
Given the following table:
ID
Price
Date
1
34
a
1
42
b
2
34
a
I would like to have one row per ID where the price was maximal
ID
Price
Date
1
42
b
2
34
a
Trying to groupby ID and selecting ID, Date, MAX(Price) results in the error GROUP BY clause with non aggregate functions
You can use row_number.
SELECT *
FROM
your_table_name
QUALIFY ROW_NUMBER() OVER (partition by id order by price desc) = 1;
The Qualify clause is used to filter the results of ordered analytical
function according to user‑specified search conditions. We can use
this conditional clause in the SELECT statement to get the particular
order values.
This question already has answers here:
Fetch the rows which have the Max value for a column for each distinct value of another column
(35 answers)
Select latest row for each group from oracle
(3 answers)
GROUP BY with MAX(DATE) [duplicate]
(6 answers)
Select First Row of Every Group in sql [duplicate]
(2 answers)
Get value based on max of a different column grouped by another column [duplicate]
(1 answer)
Closed 2 years ago.
I have a table with some fields (time, text, type). I want to build a query to return for every type the text that was introduced with the maximum value of time. Oracle has some restrictions and it is not simple to build the query without some tricks.
I am struggling to get the right query, can anyone help me with it?
TIME TEXT TYPE
--------------------------
03.05.2020 AA 2
02.04.2020 BB 2
01.04.2020 CC 1
I want a query that returns
03.05.2020 AA 2
01.04.2020 CC 1
One option would be using DENSE_RANK, FIRST and LAST Analytic Functions as
MAX(time) KEEP (DENSE_RANK LAST ORDER BY time ) OVER( PARTITION BY type )
WITH t2 AS
(
SELECT t.*, MAX(time) KEEP (DENSE_RANK LAST ORDER BY time ) OVER( PARTITION BY type )
AS highest
FROM t
)
SELECT time, text, type
FROM t2
WHERE highest = time
Through this method all the ties(repeating values for time for each type group) are listed.
Demo
First is to get the max(TIME) per type, then join it to your tableA to get other fields (TEXT).
select * from tableA t
inner join
(select max(TIME) mt, type from tableA group by type) t1 on t1.mt=t.mt and t.type= t1.type
You can use row_number (or dense_rank):
select
t.*
from (
select
t.*,
row_number() over(partition by type_column order by time_column desc) rn
from tbl t
) t
where t.rn = 1
This question already has answers here:
Fetch the rows which have the Max value for a column for each distinct value of another column
(35 answers)
GROUP BY with MAX(DATE) [duplicate]
(6 answers)
Get top results for each group (in Oracle)
(5 answers)
Select First Row of Every Group in sql [duplicate]
(2 answers)
Return row with the max value of one column per group [duplicate]
(3 answers)
Closed 5 years ago.
I have a table like this:
PROFILE_ID X_START_DATE X_END_DATE FORMER_EMPLOYER NEW_EMPLOYER START_DATE
1 2015-07-20 2016-07-20 GOOGLE BURGER KING 2017-01-01
1 2003-10-25 2009-01-14 FACEBOOK BURGER KING 2017-01-01
2 2007-10-04 2008-05-05 MICHAELS KFC 2017-01-01
2 2008-05-06 2009-05-05 GOOGLE KFC 2017-01-01
2 2009-05-06 2010-05-05 FACEBOOK KFC 2017-01-01
3 2007-10-04 2008-05-05 MCDONALDS BURGER KING 2017-01-01
What I want:
For each PROFILE_ID, I need the row, that contains the latest X_END_DATE.
For PROFILE_ID 1 I need row 1 and so on.
When I do:
Select profile_id, max(end_date)
group by 1;
I actually get what I want, but not all columns that I need. By taking more columns, I need to use them in my "groupby" statement, which is not what I want.
Thanks!!
Another way using IN and a subquery
select *
from yourtable
where (profile_id, end_date) IN
(Select profile_id, max(end_date) as end_date
from yourtable
group by profile_id);
If you prefer joins
select a.*
from yourtable a
INNER JOIN (Select profile_id, max(end_date) as end_date
from yourtable
group by profile_id) b
ON a.profile_id = b.profile_id and a.end_date b.end_date;
In oracle, this is easiest done using what's called an analytical function:
SELECT * FROM
(
SELECT
t.*,
ROW_NUMBER() OVER(PARTITION BY t.profile_id ORDER BY t.end_date DESC) as rown
FROM
yourtable t
) a
WHERE rown = 1
THe way it works is, the row_number function assigns an incrementing number to a block of rows in a partition - all rows in the same partition (same profile id) are considered for numbering. The order of the rows is specified by end_date descending (most recent first. This way we know, for every distinct profile_id value, the one with the most recent end_date will always be numbered with a 1.. Then we just select those
If you are using group by then you have to specify aggregate functions on all other columns, to ensure which row's which data you want to populate.
Remember group by will give you single record for applied column.
Select profile_id, max(end_date),
max(X_END_DATE),
max(FORMER_EMPLOYER),
max(NEW_EMPLOYER),
max(START_DATE)
group by profile_id;
No need to add all unnecessary columns in group by just add Aggregate functions on it.
This question already has answers here:
How to delete duplicate rows in SQL Server?
(26 answers)
Closed 6 years ago.
I have a table with 82,535 rows, where 65,087 rows are unique by ID. When I pull the entire result set of 82,535 and copy to Excel and remove duplicates, it shows that there are 17,448 duplicates. But when I'm using the query below I'm getting different results:
SELECT
BLD_ID, COUNT(BLD_ID) AS [BLD_ID COUNT]
FROM
Project.BreakageAnalysisOutcome_SentToAIM
GROUP BY
BLD_ID
HAVING
COUNT(BLD_ID) > = 2
This query returns a value of 17,364
I know for sure that the number of unique BLD_ID is 65,087
Most likely reason fro that is duplicate record may have more than 2 occurrence.
find duplicate count
Select COUNT(BLD_ID)- COUNT( DISTINCT BLD_ID)
From Project.BreakageAnalysisOutcome_SentToAIM
Use CTE with a Row_Number Function instead of count with group by clause and filer by Row_Number > 1.
;WITH cte
AS
(
SELECT ID,
ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ID) AS Rn
FROM [Table1]
)
DELETE cte WHERE Rn > 1