Specific SQL Ordering - sql

Bit of a newbie to SQL but I'm making my way in pretty well. My question, however, is of ordering things in a specific way. Say, for example, that I have the following table:
DATE RANGE NAME ORDER COUNT
5/5/14 - 5/6/14 Bob Food 3
5/5/14 - 5/6/14 Jim Drink 2
5/4/14 - 5/5/14 Bob Food 3
I would like to order these in a specific way:
DATE RANGE NAME ORDER COUNT
5/4/14 - 5/5/14 Bob Food 3
5/5/14 - 5/6/14 Bob Food 2
5/5/14 - 5/6/14 Jim Drink 2
To where it is ordered by where name and order are the same, count doesn't necessarily have to be the same, and that is all ordered by date range. I've tried various permutations of ORDER BY with no luck, but it seems to me like this should overall be a very simple query. Does anyone have any advice?

Here is a sqlFiddle for the code. You should GROUP BY NAME, ORDER, DATE RANGE, COUNT, then ORDER BY DATE RANGE.

Related

Excluding identical returns from ACCESS query when names are equal

In MS ACCESS, I have a table containing names and dates for when a persons yearly exam expires. This exam is valid for 12 months, so the next exam is typically done before all 12 months have expired.
Table, called "Exam", looks like this (in the real table names are unique):
ID Name Dateexp
1 Peter 30/07/2020
2 john 10/09/2020
3 Bob 11/10/2019
4 Peter 25/06/2021
I have a query that shows the persons with a "valid" exam. I looks like this:
SELECT Name As Name, Dateexp As Expiry FROM Overall WHERE Dateexp > now();
It returns:
Name Expiry
Peter 30/07/2020
John 10/09/2020
Peter 25/06/2021
Problem is that "Peter" has done a new exam thereby extending his expiry date from 30/07/2020 to 25/06/21 and I only want the latest one to be shown.
Query should return:
Name Expiry
Peter 25/06/2021
John 10/09/2020
I am truly lost - does anyone have an idea as to how this can be solved?
Thank you!
You can use max and having clause:
Select name, max(dateexp) as dateexp
from overall
Group by name
Having max(dateexp) > now()
If I followed you correctly, you can just use aggregation, and filter with a having clause:
select name, max(dateexp) as expiry
from overall
group by name
having max(dateexp) > now();
This filters on names whose latest expiry date is in the future.

Conditional Sum SQL

I am very new to SQL and have been presented with, what seems to me, a complex task. I have a table which is generating the number of various fruit purchased on a given day. Thus:
G. A G.B
2016-06-01 Banana 45 0
2016-06-01 Pear 158 0
2016-06-01 apple 0 23
.... dates continue
I need to develop some kind of conditional sum to count how many types of fruit are bought with a specific grade on a specific date. So in the above case on the given date (2016-06-01) there would be 203 Grade A (G.A) bits of fruit and 23 Grade B (G.B) pieces of fruit.
Naturally some kind of
Sum(case when date=date then Grade else 0 ).
But, I am really baffled here. Please, any help would be greatly appreciated!!!!
A simple group clause should do the job here (Note: untested code)
select date, sum(grade_a) as grade_a_sum, sum(grade_b) as grade_b_sum
from sales
group by date;
This will give the grades for every date. Individual dates can then be selected if necessary.
Won't simple group by do the work..
Select
date,
sum(GA) as GA,
sum(GB) as GB
from
Table
group by date

SQL Totals Query with non-aggregate fields

=================
ID - Date - Note
3 - 1/1/2014 - happy
3 - 2/1/2014 - mad
3 - 3/1/2014 - sad
4 - 1/1/2014 - mad
4 - 2/1/2014 - happy
=================
Would like to return the latest date per ID as well as associated Note. Results would look like this:
=================
ID - Date - Note
3 - 3/1/2014 - sad
4 - 2/1/2014 - happy
=================
I can group by ID and then select the max(Date). However, I can't get the associated Note as no aggregate function is applicable. I just want: "the note associated with the Id/date I selected via the max function."
I don't know the official or proper or efficient way to do it. It feels like i'm hacking it by rejoining the aggregate query back into the original data set. Any help would be greatly appreciated as i constantly run into this issue.
One easy way is to wrap the max query in a subselect:
select
m.id, m.datecolumn, m.note
from
(select max(datecolumn) datecolumn, id
from mytable
group by id) sub
inner join mytable m on m.id = sub.id and m.datecolumn= sub.datecolumn

Using SQLite to display repeated and new entries

I have a table with 5 columns, but I really need only information from two. Here is an example of that table, though mine has 1600+ records:
Date Name
2/18 Bob
2/18 Karen
2/19 Fred
2/20 Jared
2/21 Fred
2/22 Bob
2/23 Steve
2/24 Bob
2/25 Jared
I would like to set a date range and find which names were repeats and which were new. For example, if I did this for 2/18-2/21 and 2/22-2/25, I would see that in 2/22-2/25 Bob and Jared were also found in the 2/18-2/21 date range and that Steve was "new." Does anyone have any ideas on a SQLite query to accomplish this task?
You can do this using conditional aggregation, assuming your dates are really in a reasonable format.
select name,
(case when min(date> < STARTDATE then 'RETURNING'
else 'NEW'
end)
from table t
where date between STARTDATE and ENDDATE
group by name;

How can I specify the order of results within groups when querying Derby?

I am using a Derby database.
I have a table like this:
TB_ORDERS
BUYER_NAME DATE_CREATED OTHER_COLLUMS ......
---------------------------------------------
DAVID 2012-09-01 ----
PETER 2012-09-14 ----
DAVID 2012-09-05 ----
PETER 2012-09-02 ----
DAVID 2012-08-15 ----
MARY 2012-09-02 ----
MARY 2012-09-15 ----
I am trying to get a result grouped by BUYER_NAME where each group should be ordered by DATE_CREATED and finally everything ordered by the group's most recent date, like this:
MARY 2012-09-15
MARY 2012-09-12
PETER 2012-09-14
PETER 2012-09-02
DAVID 2012-09-05
DAVID 2012-09-01
DAVID 2012-08-15
As you can see, the Mary's Group has the most recent date_created so it is placed on top.
Then we get Peter's group on second place (note that Peter's group has a date "09-14" higher then one date on Mary's group "09-12" however, Peter's group is placed after Mary's group as every thing should be ordered by the group's most recent date.
I have tried every thing I know with no success. The closest I got was:
Select date_created, buyer_name
From ORDERS
Order By buyer_name,date_created Desc;
However, the groups are not ordered by the most recent group date.
Should I do that in my code or is there a better way?
This query will bring you the most recent date_created of each buyer_name, together with the result set that you already had. If you include this new column in your Order By clause it should do the trick:
Select o.date_created, o.buyer_name,
(select max(date_created) from orders where buyer_name = o.buyer_name) as most_recent_date
From ORDERS o
Order By most_recent_date, o.buyer_name, o.date_created Desc
Henrique, thank you for such an elegant solution. I have tried for at least 3 days before posting the problem.
Now, I've got a new one. When I try to paginate the query for 3 itens per page, I get Petter in the first page and again in the second page. To solve this problem I am using a subquery where I select all distinct date_created grouped by buyers, and that is where I do my pagination. It works. However, it is not elegant and efficient like yours.
This is my poor solution (I've added a new line "WHERE"):
Select o.date_created, o.buyer_name,
(select max(date_created) from orders where buyer_name = o.buyer_name) as most_recent_date
From ORDERS o
where buyer_name in (SELECT buyer_name FROM ORDERS WHERE date_created in (SELECT MAX(date_created) FROM ORDERS GROUP BY buyer_name ORDER BY 1 DESC OFFSET 3 ROWS FETCH NEXT 3 ROWS ONLY))
Order By most_recent_date, o.buyer_name, o.date_created ASC
PS: the resultset shows the oldest date first and for that I am using a
Collections.reverse(list);
Knowledge is good but imagination is better.
Tks again for your time, Armando