This question already has answers here:
Get top 1 row of each group
(19 answers)
Group by minimum value in one field while selecting distinct rows
(10 answers)
Closed 14 days ago.
How can I group by (property_id) and extract the data (travel_date) for the entry with the minimum value (total_price) per group?
I'm using MS SQL Server, but happy to convert from any other SQL-RDBMS example.
Database table looks like:
trip_id, property_id, travel_date, total_price
1, 1, 2023-04-01, 1000
2, 1, 2023-04-02, 1100
3, 1, 2023-04-03, 1200
4, 2, 2023-04-01, 1000
5, 2, 2023-04-02, 900
6, 2, 2023-04-03, 2200
Desired result looks like:
trip_id, property_id, travel_date, MIN(total_price)
1, 1, 2023-04-01, 1000
5, 2, 2023-03-02, 900
I have a ton of WHERE clauses in the real query, so ideally looking to avoid a subquery which would need to duplicate all the WHERE's.
Related
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)
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)
Get value based on max of a different column grouped by another column [duplicate]
(1 answer)
Closed 4 months ago.
I have a table that is a collection entries of users' information:
username, date, sequence, value
--------------------------
Hannah, 1/2/2010, 0, peach
Kim, 1/3/2010, 0, watermelon
Hannah, 8/4/2009, 0, mango
David, 2/2/2010, 0, apple
David, 2/2/2010, 1, orange
David, 1/3/2010, 0, banana
...
I want to create a query that would give me the latest date and then the latest sequence for each user?
For example, the result will be:
Hannah, 1/2/2010, 0, peach
Kim, 1/3/2010, 0, watermelon
David, 2/2/2010, 1, orange
In details of the result, David has two latest data records:
David, 2/2/2010, 0, apple
David, 2/2/2010, 1, orange
and then from these two records, the latest sequence is 1, so the final result is:
David, 2/2/2010, 1, orange
Thank you so much if anyone can help me with this. The table is huge so the query would need to be very efficient, otherwise, it exceeds call limit on CPU usage.
select x.username,x.date,x.sequence,x.value from
(
select t.username, t.date, t.sequence, t.value,
row_number()over(partition by t.username order by t.date desc,t.sequence desc)xcol
from your_table t
)x where x.xcol=1
I would like to run the below query that looks like this for week 1:
Select week(datetime), count(customer_call) from table where week(datetime) = 1 and week(orderdatetime) < 7
... but for weeks 2, 3, 4, 5 and 6 all in one query and with the 'week(orderdatetime)' to still be for the 6 weeks following the week(datetime) value.
This means that for 'week(datetime) = 2', 'week(orderdatetime)' would be between 2 and 7 and so on.
'datetime' is a datetime field denoting registration.
'customer_call' is a datetime field denoting when they called.
'orderdatetime' is a datetime field denoting when they ordered.
Thanks!
I think you want group by:
Select week(datetime), count(customer_call)
from table
where week(datetime) = 1 and week(orderdatetime) < 7
group by week(datetime);
I would also point out that week doesn't take the year into account, so you might want to include that in the group by or in a where filter.
EDIT:
If you want 6 weeks of cumulative counts, then use:
Select week(datetime), count(customer_call),
sum(count(customer_call)) over (order by week(datetime)
rows between 5 preceding and current row) as running_sum_6
from table
group by week(datetime);
Note: If you want to filter this to particular weeks, then make this a subquery and filter in the outer query.
This question already has answers here:
SQL Server : SUM() of multiple rows including where clauses
(6 answers)
Closed 8 years ago.
I know this is probably a simple question since I'm still learning, but I am trying to find a SQL Select statement that will calculate the SUM of each row's pieces and weight IF their secondary IDs are the same. So the select is collapsing and getting the SUM of rows with the same secondary ID, while also returning the unique rows as well.
ID_a ID_b pieces weight
--------------------------
1 1 10 20
2 1 20 30
3 2 40 40
Will result in
ID_b: 1 pieces: 30 weight: 50
ID_b: 2 pieces: 40 weight: 40
Thank you.
Group by the id_b and then you can use aggregate functions to sum up the values for each group
select id_b, sum(pieces), sum(weight)
from your_table
group by id_b
select id_b,sum(pieces),sum(weight)
from table
group by id_b
Here is the query you're looking for:
SELECT TID_b
,SUM(pieces) AS [totalPieces]
,SUM(weight) AS [totalWeight]
FROM yourTable T
GROUP BY T.ID_b
Hope this will help you.
I have strings like FVS101209GO5 Stored in a MS Access data table, I want to count the number of strings in a certain year, so in the example that would be the year 2010
I was doing
query = "SELECT SUM( IIF( Mid( KEYLastName, 4, 2) , 1,0)) AS occur FROM MyTable WHERE Year(mydate)=2010 ;"
The length of the string is 12 or 13, for the examples #JW added
qwe123456XXX - 2012
asd345678XXX - 2034
FVS101209GO5 - 2010
If you wish to find the count of occurrences of various years within a string, you might like to use:
SELECT Mid([KEYLastName],4,2) AS [Year],
Count(KEYLastName) AS CountOfOccurances
FROM MyTable
GROUP BY Mid([KEYLastName],4,2)
This will return all the two digit years at (4,2) and the number of times they each occur.
Edit re Comments
SELECT KEYLastName,
Mid([KEYLastName],4,2) AS [Year],
DCount("*","MyTable","Mid([KEYLastName],4,2)="
& Mid([KEYLastName],4,2)) AS YearCount
FROM MyTable
Seems the 4th and 5th characters in KEYLastName represent the last 2 digits of a year, so "FVS101209GO5" is for 2010. If that is correct you can count the number of KEYLastName values which represent 2010 with either of these 2 queries:
SELECT Sum(IIf(Mid(KEYLastName, 4, 2) = "10", 1, 0)) AS occur
FROM MyTable;
SELECT Count(IIf(Mid(KEYLastName, 4, 2) = "10", 1, Null)) AS occur
FROM MyTable;
However, I'm unsure why you also have a WHERE clause to restrict the rows to those where mydate is from 2010. If you want that, too, create an index on mydate and include this WHERE clause in one of the above queries.
WHERE mydate >= #2010-1-1# AND mydate < #2011-1-1#
With an index on mydate that should be much faster than asking the db engine to apply the Year() function to the mydate value from every row in the table.
I have a big table that contains records for each reporting period in my project.
The period is indentified by an integer 1, 2, 3, 4, 5, 6, 7.
Each period contains about 7000 rows of tasks each identified a unique ID. These tasks all have a percent complete column which is an integer.
I want to add a comparison column.
so it would look up the unique id in the previous period then return the difference in percent complete.
eg
for
Period: 8 Item Unique ID: 42w3wer324wer32 Percent complete: 50
it would find:
Period: 7 Item Unique ID: 42w3wer324wer32 Percent complete: 40
the fill in the field with: 10.
If it could not find the Item Unique ID in the previous period then it would default to 0.
thanks
As I understand your description, you could pull the data for period 8 like this:
SELECT item_id, pct_complete
FROM YourTable
WHERE rpt_period = 8;
And the previous period would be the same query except substituting 7 as the period.
So take the period 8 query and left join it to a subquery for period 7.
SELECT
y.item_id,
(y.pct_complete - Nz(sub.pct_complete, 0)) AS change_in_pct_complete
FROM YourTable AS y
LEFT JOIN
(
SELECT item_id, pct_complete
FROM YourTable
WHERE rpt_period = 7
) AS sub
ON y.item_id = sub.item_id
WHERE rpt_period = 8;
That Nz() expression will substitute 0 for Null when no period 7 match exists for a period 8 item_id.
If you need a query which will not be running from within an Access session, the Nz() function will not be available. In that case, you can use an IIf() expression ... it's not as concise, but it will get the job done.
IIf(sub.pct_complete Is Null, 0, sub.pct_complete)