I have following query to solve:
"List the Member(s) who are born in and after 1990 and have organised the Hackathons that have received funding from the project(s) that have the highest number of labs co-working on them."
SELECT Member.email, Member.firstName, Member.lastName, Member.dateOfBirth,
Hubs.organiserMember, MAX(LabInProject.projectID)
FROM LabInProject
INNER JOIN Project ON LabInProject.projectID=Project.projectID
INNER JOIN Hackathon ON Project.projectID=Hackathon.fundingProject
INNER JOIN Hubs ON Hackathon.eventID=Hubs.eventID
INNER JOIN Member ON Member.email=Hubs.organiserMember
WHERE LabInProject.projectID = (SELECT MAX(LabInProject.projectID) FROM LabInProject)
GROUP BY Hubs.organiserMember
HAVING Member.dateOfBirth > '1990'
The SELECT MAX gives me the highest projectID (number) in the row, NOT the highest COUNT of projectID.
How do I get the "MAX COUNT" of projectID in table: LabInProject?
I have tried by making a subquery with a derived table: totalCount, but I don't know how to connect this with the joins, it's not working.
HAVING COUNT(*) =
(
SELECT COUNT(projectID) totalCount
FROM LabInProject
GROUP BY projectID
LIMIT 1
)
WHERE LabInProject.projectID = (SELECT MAX(LabInProject.projectID) FROM LabInProject)
You have a Syntax-Error here.
Try to post the closing bracket at the end of the statement.
Consider the below derived table in an inner join with its own derived tables to replace the earlier WHERE condition. This should return multiple projects that share same maximum counts:
...
INNER JOIN
-- OBTAIN PROJECT AND COUNTS CONDITIONED TO THE MAX
(SELECT sub.ProjectID, Count(*) As ProjectIDCount
FROM LabInProject sub
INNER JOIN Project ON LabInProject.projectID=Project.projectID
INNER JOIN Hackathon ON Project.projectID=Hackathon.fundingProject
INNER JOIN Hubs ON Hackathon.eventID=Hubs.eventID
INNER JOIN Member ON Member.email=Hubs.organiserMember
WHERE Member.dateOfBirth > '1990'
GROUP BY sub.ProjectID
HAVING Count(*) IN
-- OBTAIN SCALAR VALUE OF MAX PROJECT COUNT
(SELECT Max(dT.ProjectIDCount) As MaxOfProjectIDCount
FROM
-- OBTAIN PROJECT COUNTS
(SELECT subdT.ProjectID, Count(*) As ProjectIDCount
FROM LabInProject subdT
INNER JOIN Project ON LabInProject.projectID=Project.projectID
INNER JOIN Hackathon ON Project.projectID=Hackathon.fundingProject
INNER JOIN Hubs ON Hackathon.eventID=Hubs.eventID
INNER JOIN Member ON Member.email=Hubs.organiserMember
WHERE Member.dateOfBirth > '1990'
GROUP BY subdT.ProjectID) As dT)
) As temp
ON LabInProject.projectID = temp.projectID
...
Related
This is a slight variant of the question I asked here
SQL Query for getting maximum value from a column
I have a Person Table and an Activity Table with the following data
-- PERSON-----
------ACTIVITY------------
I have got this data in the database about users spending time on a particular activity.
I intend to get the data when every user has spent the maximum number of hours.
My Query is
Select p.Id as 'PersonId',
p.Name as 'Name',
act.HoursSpent as 'Hours Spent',
act.Date as 'Date'
From Person p
Left JOIN (Select MAX(HoursSpent), Date from Activity
Group By HoursSpent, Date) act
on act.personId = p.Id
but it is giving me all the rows for Person and not with the Maximum Numbers of Hours Spent.
This should be my result.
You have several issues with your query:
The subquery to get hours is aggregated by date, not person.
You don't have a way to bring in other columns from activity.
You can take this approach -- joins and group by, but it requires two joins:
select p.*, a.* -- the columns you want
from Person p left join
activity a
on a.personId = p.id left join
(select personid, max(HoursSpent) as max_hoursspent
from activity a
group by personid
) ma
on ma.personId = a.personId and
ma.max_hoursspent = a.hoursspent;
Note that this can return duplicates for a given person -- if there are ties for the maximum.
This is written more colloquially using row_number():
select p.*, a.* -- the columns you want
from Person p left join
(select a.*,
row_number() over (partition by a.personid order by a.hoursspent desc) as seqnum
from activity a
) a
on a.personId = p.id and a.seqnum = 1
ma.max_hoursspent = a.hoursspent;
I have one table for reports. My first select query is that combines all sales tables
SELECT *, ds_sales.id_sales
FROM ds_sales LEFT JOIN
ds_payment
ON ds_sales.id_sales=ds_payment.id_sales LEFT JOIN
customer_info
ON ds_payment.id_customer=customer_info.id_customer INNER JOIN
ds_salesdetails
ON ds_salesdetails.id_sales=ds_sales.id_sales
WHERE customer_info.id_customer = '".$_POST["id_customer"]."'
This is the result of the query
and my second query is this, to filter the same sales serial number, since the ds_salesdetails table have many sales serial number
select ds_salesdetails.id_sales, count(*),
group_concat(ds_salesdetails.id_product)
from ds_salesdetails
having count(*) >= 1
I need to merge them to create a report for customers sales.
Join with the grouped subquery instead of the whole table.
SELECT *, ds_sales.id_sales
FROM ds_sales LEFT JOIN
ds_payment
ON ds_sales.id_sales=ds_payment.id_sales LEFT JOIN
customer_info
ON ds_payment.id_customer=customer_info.id_customer LEFT JOIN
(SELECT id_sales, count(*) as product_count,
group_concat(ds_salesdetails.id_product) AS product_list
from ds_salesdetails
GROUP BY id_sales) AS grouped ON grouped.id_sales = ds_sales.id_sales
WHERE customer_info.id_customer = '".$_POST["id_customer"]."'
SELECT distinct referrals.listing_id,submissions.listing_name
FROM submissions
INNER JOIN referrals ON referrals.listing_id=submissions.listing_id;
if i do
SELECT distinct referrals.listing_id,submissions.listing_name,referrals.timestamp
FROM submissions
INNER JOIN referrals ON referrals.listing_id=submissions.listing_id;
it gives me many others records without distinct listing_id
i want distinct listing_id with their timestamps(which are not distinct but are according to distinct listing_id)
Use aggregation, if you want one row per listing. For instance:
SELECT r.listing_id, s.listing_name, max(r.timestamp) as most_recent_timestamp
FROM submissions s INNER JOIN
referrals r
ON r.listing_id = s.listing_id
GROUP BY r.listing_id, s.listing_name;
SELECT DISTINCT applies to all the expressions in the SELECT.
i have table with student_uid,grade,test_name as columns i want to count how many got each grade..for this
SELECT a.grade,COUNT(a.grade) AS count1
FROM 2015_2016_x_english_grades AS a
where test_name='ut1_marks'
GROUP BY grade
for single table worked how to do it for more than one table
my query:
SELECT a.grade, COUNT(a.grade),b.grade,COUNT(b.grade)
FROM 2015_2016_x_english_grades a
INNER JOIN 2015_2016_x_hindi_grades b ON a.grade=b.grade
WHERE a.test_name = b.ut1_marks='ut1_marks'
GROUP BY a.grade,b.grade
what is wrong in this?
i also tried this
SELECT a.grade,COUNT(a.grade),(SELECT COUNT(b.grade)FROM 2015_2016_x_biology_grades b where b.test_name='ut1_marks' GROUP BY b.grade)as count1 FROM 2015_2016_x_biology_grades a where test_name='ut1_marks' GROUP BY a.grade
it says [Err] 1242 - Subquery returns more than 1 row
Do the counting in subqueries, and join the subqueries.
SELECT e.grade, english_count, hindi_count
FROM (SELECT grade, COUNT(*) AS english_count
FROM 2015_2016_x_english_grades
WHERE test_name = 'ut1_marks'
GROUP BY grade) AS e
JOIN (SELECT grade, COUNT(*) as hindi_count
FROM 2015_2016_x_hindi_grades
WHERE test_name = 'ut1_marks'
GROUP BY grade) AS h
ON e.grade = h.grade
Or if there's a unique key in each table, you can do:
SELECT e.grade, COUNT(DISTINCT e.id) AS english_count, COUNT(DISTINCT h.id) AS hindi_count
FROM 2015_2016_x_english_grades AS e
JOIN 2015_2016_x_hindi_grades AS h ON e.grade = h.grade AND e.test_name = h.test_name
WHERE e.test_name = 'ut1_marks'
GROUP BY e.grade
Note that both of these queries will only show a grade if it exists in both tables. To get grades that only exist in one table, you need a FULL OUTER JOIN, but MySQL doesn't have this operation. See
Full Outer Join in MySQL
for how to emulate them.
This query is working fine. It gives a count of contest entrants for whom the contact id in contest_entries is their origin_contact in the person table.
SELECT c.handle, COUNT(*)
FROM `contest_entry` ce,
person p,
contest c
WHERE
p.origin_contact = ce.contact AND
c.id = ce.contest
GROUP BY c.id
I want to now query how many of those records also have at least one record where the contact id matches in email_list_subscription_log BUT that table may have many log records for any one contact id.
How do I write a join that gives me a count that is not inflated by the multiple records?
Should I use a version of my first query to get all of the contact ids into a tmp table and just use that?
Not sure which field is contact id, but you can do something like this:
select c.handle,
count(*) as count
from `contest_entry` ce
inner join person p on p.origin_contact = ce.contact
inner join contest c on c.id = ce.contest
where exists (
select 1
from email_list_subscription_log l
where l.contact_id = ce.contact
)
group by c.id
You ought to deflate the email_list_subscription_log with DISTINCT or GROUP:
SELECT c.handle, COUNT(*)
FROM `contest_entry` ce
JOIN person p ON (p.origin_contact = ce.contact)
JOIN contest c ON (c.id = ce.contest)
JOIN (SELECT DISTINCT contact, email FROM email_list_subscription_log ) AS elsuniq
ON (ce.contact = elsuniq.contact)
[ WHERE ]
GROUP BY c.id
Using GROUP in the subquery you might count the number of records while still returning one row per element:
JOIN (SELECT contact, count(*) AS elsrecords FROM email_list_subscription_log
GROUPY BY contact) AS elsuniq
With this JOIN syntax, the WHERE is not necessary, but I kept it there if you need additional filtering.