In the booking table I'm using, the fields are FlightNo, CustomerNo, DateOfFlight, DateBooked
I'm trying to find the flight number of the most booked flight. I have 5 bookings for flight101 and 2 for flight105 but the below code is returning flight105 as the result.
SELECT distinct(flightNo)
FROM booking
WHERE flightNo IN
(SELECT max(flightNo) AS maximum FROM booking);
I think you could use a group by to fix
select flightNo, count(*) from booking group by flightNo
Here you are grouping the results to flightNo and counting all the records given this flightNo. If you want to only display 1 record the most booked flight order it by count(*) desc and limit the results to 1.
select flightNo, count(*) from booking group by flightNo order by count(*) desc limit 1
Related
I have two tables in an Oracle Database, one of which is all the purchases done by all the customers over many years (purchase_logs). It has a unique purchase_id that is paired with a customer_id.The other table contains the user info of all the customers. Both have a common key of customer_id.
I want to display the user info of customers who have more than 1 unique item (NOT the item quantity) purchased in any month (i.e if A customer bought 4 unique items in february 2020 they would be valid as well as someone who bought 2 items in june). I was wondering what should my correct approach be and also how to correct execute that approach.
The two approaches that I can see are
Approach 1
Count the overall number of purchases done by all customers, filter the ones that are greater than 1 and then check if they any of them were done within a month.
Use this as a subquery in the where clause of the main query for retrieving the customer info for all the customer_id which match this condition.
This is what i've done so far,this retrieves the customer ids of all the customers who have more than 1 purchases in total. But I do not understand how to filter out all the purchases that did not occur in a single arbitrary month.
SELECT * FROM customer_details
WHERE customer_id IN (
SELECT cust_id from purchase_logs
group by cust_id
having count(*) >= 2);
Approach 2
Create a temporary table to Count the number of monthly purchases of a specific user_id then find the MAX() of the whole table and check if that MAX value is bigger than 1 or not. Then if it is provide it as true for the main query's where clause for the customer_info.
Approach 2 feels like the more logical option but I cannot seem to understand how to write the proper subquery for it as the command MAX(COUNT(customer_id)) from purchase_logs does not seem to be a valid query.
This is the DDL diagram.
This is the Sample Data of Purchase_logs
Customer_info
and Item_info
and the expected output for this sample data would be
It is certainly possible that there is a simpler approach that I am not seeing right now.
Would appreciate any suggestions and tips on this.
You need this query:
SELECT DISTINCT cust_id
FROM purchase_logs
GROUP BY cust_id, TO_CHAR(purchase_date, 'YYYY-MON')
HAVING COUNT(DISTINCT item_id) > 1;
to get all the cust_ids of the customers who have more than 1 unique item purchased in any month and you can use with the operator IN:
SELECT *
FROM customer_details
WHERE customer_id IN (
SELECT DISTINCT cust_id -- here DISTINCT may be removed as it does not make any difference when the result is used with IN
FROM purchase_logs
GROUP BY cust_id, TO_CHAR(purchase_date, 'YYYY-MON')
HAVING COUNT(DISTINCT item_id) > 1
);
One approach might be to try
with multiplepurchase as (
select customer_id,month(purchasedate),count(*) as order_count
from purchase_logs
group by customer_id,month(purchasedate)
having count(*)>=2)
select customer_id,username,usercategory
from mutiplepurchase a
left join userinfo b
on a.customer_id=b.customer_id
Expanding on #MT0 answer:
SELECT *
FROM customer_details CD
WHERE exists (
SELECT cust_id
FROM purchase_logs PL
where CD.customer_id = PL.customer_id
GROUP BY cust_id, item_id, to_char(purchase_date,'YYYYMM')
HAVING count(*) >= 2
);
I want to display the user info of customers who have more than 1 purchases in a single arbitrary month.
Just add a WHERE filter to your sub-query.
So assuming that you wanted the month of July 2021 and you had a purchase_date column (with a DATE or TIMESTAMP data type) in your purchase_logs table then you can use:
SELECT *
FROM customer_details
WHERE customer_id IN (
SELECT cust_id
FROM purchase_logs
WHERE DATE '2021-07-01' <= purchase_date
AND purchase_date < DATE '2021-08-01'
GROUP BY cust_id
HAVING count(*) >= 2
);
If you want the users where they have bought two-or-more items in any single calendar month then:
SELECT *
FROM customer_details c
WHERE EXISTS (
SELECT 1
FROM purchase_logs p
WHERE c.customer_id = p.cust_id
GROUP BY cust_id, TRUNC(purchase_date, 'MM')
HAVING count(*) >= 2
);
I have 2 tables, STUDENT(stu_id, name) and PROJECT(project_id, name), linked together by TASK(stu_id, project_id, duration), how can I find student with the number of projects is the largest while the duration of all that projects is the least? I've already tried this, but it's definitely wrong, since it find MAX COUNT PROJECT then join with MIN SUM DURATION, not MAX COUNT PROJECT AND MIN SUM DURATION
--WRONG
SELECT S.stu_id, S.stu_name
FROM STUDENT AS S
LEFT JOIN TASK AS T
ON S.stu_id = T.stu_id
GROUP BY S.stu_id, S.stu_name
HAVING COUNT(T.project_id) >= ALL(
SELECT COUNT(T1.project_id)
FROM TASK AS T1
GROUP BY T1.stu_id
)
AND SUM(T.duration) <= ALL(
SELECT SUM(T2.duration)
FROM TASK AS T2
GROUP BY T2.stu_id
)
how can I find student with the number of projects is the largest while the duration of all that projects is the least?
This sounds like aggregation and limiting:
select top (1) stu_id, count(*) as num_projects, sum(duration) as total_duration
from task
group by stu_id
order by count(*) desc, sum(duration) asc;
I am trying to distinct and then find the count of the teams a player played for in any single season and number of teams he played for. This is tripping me up and ofcourse i have a sample down below(2nd) one. The first ones is my failed attempt
SELECT o.id,o.year,COUNT(DISTINCT(o.team)) b JOIN
(SELECT id, year, team FROM batting
GROUP BY id,year,team
ORDER BY id DESC
LIMIT 25) o
0.id =b.id;
SELECT id, year, team FROM batting
GROUP BY id,year,team
ORDER BY id DESC
LIMIT 25;
produces
IGNORE the ^A, i think they represent either space or comma, just column seperatpr
Get the count of teams for each player for each year and order by the count desc,get the 1 row
SELECT id, year, COUNT(DISTINCT(team)) FROM batting
GROUP BY id,year
ORDER BY COUNT(DISTINCT(team)) DESC
LIMIT 1;
I have a requests table which include request data for my my page requests. I have field including Id, UserAgent, Ip, EventDateUtc, etc. How to write SQL which give me average requests per day.
You can get a count grouped by UserAgent,EventDateUtc and then do a AVG on top of it.
SELECT AVG(reccount) avg_count,EventDateUtc
FROM
(
SELECT COUNT(*) reccount,UserAgent, CONVERT(DATE,EventDateUtc) EventDateUtc
FROM PageVisit
GROUP BY CONVERT(DATE,EventDateUtc),UserAgent
)T
GROUP BY EventDateUtc
If you want a total average for all days, don't do a GROUP BY in the outer query.
SELECT AVG(reccount) avg_count
FROM
(
SELECT COUNT(*) reccount,UserAgent, CONVERT(DATE,EventDateUtc) EventDateUtc
FROM PageVisit
GROUP BY CONVERT(DATE,EventDateUtc),UserAgent
)T
The inner select counts visits / day, the outer the average:
select avg(cnt)
from (select count(*) as cnt
from tablename
group by EventDateUtc)
I have an orders table. I want to search if the customer has ordered for the first time or not. We can use email_id field in orders table to check it. But how can I check it using an SQL query? That is, I want to search the first order of the particular customer. How can I do it?
try this one:
SELECT email_id, IF(COUNT(email_id) > 0, 'NOT', 'First Time') AS Status
FROM `Orders`
WHERE email_id = 'EMAILADDRESSHERE'
GROUP BY email_id
Use below query
select * from orders where email_id='myid#mysite.com'
if there is data in this query, it means that particular customer is not ordering for first time...
Hope this is what you want...
Update 1
Try this...
select emailid, count(emailid) as total from order where 1=1 group by emailid order by total
this will give you below output
emailid total
++++++++++++++++++++
my1#mm.com 1
my2#mm.com 4
my3#mm.com 6
Also check what you get for select emailid, count(emailid) as total from order where total>1 group by emailid order by total
As I don't have sql here, I can't check :(
Good Luck
First order:
T-SQL:
SELECT TOP 1 *
FROM orders
WHERE email_id='myid#mysite.com'
ORDER BY order_date DESC
PostgreSQL / MySQL:
SELECT
FROM orders
WHERE email_id='myid#mysite.com'
ORDER BY order_date DESC
LIMIT 1
Interbase:
SELECT FIRST 1 SKIP 0
FROM orders
WHERE email_id='myid#mysite.com'
ORDER BY order_date DESC