I have the following tables:
users
id | fname | lname
1 | Ron | Jones
2 | Jon | Don
3 | Sam | Bolt
niche
id | name
1 | Arts
2 | Sports
3 | Fashion
compensation
id | type
1 | Monetary Payments
2 | Free Products
3 | Experiences
Then I have two reference tables:
user_niche
id | userid | nicheid
1 | 1 | 2
2 | 1 | 3
3 | 2 | 1
4 | 2 | 3
5 | 3 | 1
6 | 3 | 2
And finally user_comp
id | userid | compid
1 | 1 | 1
2 | 1 | 2
3 | 2 | 3
4 | 3 | 1
5 | 3 | 2
6 | 3 | 3
What I want to achieve through query is as follows:
users.id | users.fname | users.lname | niches | compensations
1 | Ron | Jones | Sports, Fashion | Monetary Payments, Free Products
2 | Jon | Don | Arts, Fashion | Experiences
3 | Sam | Bolt | Arts, Sports | Monetary Payments, Free Products, Experiences
But my query (as follows) keeps repeating the niches and compensations in a way I cannot understand. Can someone please help me accomplish the required result?
SELECT users.id, users.fname, users.lname, GROUP_CONCAT(niche.name) AS niches, GROUP_CONCAT(compensation.type) AS compensations
FROM users
JOIN user_niche ON users.id = user_niche.userid
JOIN user_comp ON users.id = user_comp.userid
JOIN niche ON user_niche.nicheid = niche.id
JOIN compensation ON user_comp.compid = compensation.id
GROUP BY users.id
Help and suggestion is much appreciated.
Related
Consider the following sample table from a soccer tournament (let's call this table matches)
+----------+---------+--------------+
| match_id | club_id | goals_scored |
+----------+---------+--------------+
| 1 | 1 | 1 |
| 1 | 2 | 0 |
| 2 | 1 | 1 |
| 2 | 3 | 1 |
| 3 | 1 | 0 |
| 3 | 4 | 2 |
| 4 | 2 | 2 |
| 4 | 3 | 4 |
| 5 | 2 | 4 |
| 5 | 4 | 0 |
| 6 | 3 | 1 |
| 6 | 4 | 1 |
+----------+---------+--------------+
The resulting table we want should give us each club's total goals scored AND goals conceded:
+---------+--------------+----------------+
| club_id | goals_scored | goals_conceded |
+---------+--------------+----------------+
| 1 | 2 | 4 |
| 2 | 6 | 4 |
| 3 | 6 | 4 |
| 4 | 3 | 5 |
+---------+--------------+----------------+
Getting goals scored is straight forward enough...
SELECT SUM(goals_scored),
club_id
FROM matches
GROUP BY club_id
but I am absolutely flummoxed as to how to get it for each team's opponents.
I could, of course, construct a pretty complex array of subqueries to get there. If this were application-side work I'd likely just stuff it in a loop and iterate over each club to get there, but my use case requires a SQL answer if possible. Any thoughts?
edit: also if anyone has any better ideas on how to title this question, I'm all ears - I'm not really sure exactly how to describe this problem in the first place.
We can use a self-join approach here:
SELECT
m1.club_id,
SUM(m1.goals_scored) AS goals_scored,
SUM(m2.goals_scored) AS goals_conceded
FROM matches m1
INNER JOIN matches m2
ON m2.match_id = m1.match_id AND
m2.club_id <> m1.club_id
GROUP BY
m1.club_id
ORDER BY
m1.club_id;
This approach brings the goals conceded by each club to the other club, for each match, into a single row. We then just aggregate by club to get the two sums.
I need a help with mySQL SELECT query from multiple tables. I have got four tables: school, discipline, pupils and teams.
School table looks like:
+------+---------+---------------+----------+
| id | name | discipline_id | pupil_id |
+------+---------+---------------+----------+
| 1 | one | 2 | 5 |
+------+---------+---------------+----------+
| 2 | two | 3 | 8 |
+------+---------+---------------+----------+
| 3 | three | 4 | 12 |
+------+---------+---------------+----------+
Discipline table looks like:
+------+---------+
| id | name |
+------+---------+
| 1 | math |
+------+---------+
| 2 | bio |
+------+---------+
| 3 | liter |
+------+---------+
| 4 | geo |
+------+---------+
Teams table looks like:
+------+---------+---------------+-----------+
| id | name | school_id | member_id |
+------+---------+---------------+-----------+
| 1 | T1 | 1 | 3 |
+------+---------+---------------+-----------+
| 2 | T2 | 3 | 3 |
+------+---------+---------------+-----------+
| 3 | T3 | 2 | 9 |
+------+---------+---------------+-----------+
The result of disciplines I need to get with a "SELECT from discipline..." query by "member_id = 3" is:
+-----------------+---------------+
| discipline_name | discipline_id |
+-----------------+---------------+
| bio | 2 |
+-----------------+---------------+
| geo | 4 |
+-----------------+---------------+
By matching member's school and then getting its discipline, if it makes sense...Is it possible to do with just one mySQL query?
Type of: member_id 3 => school_id 1,3 => discipline_id = show related disciplines names and ids which are 2, 4
Thank you very much...
Your goal is not clear or makes no sense to me.
But here is what you are literally asking for:
SELECT
s.discipline_id
d.name
FROM teams t
LEFT JOIN school s
ON s.id = t.school_id
LEFT JOIN discipline d
ON d.id = s.discipline_id
WHERE t.member_id = 3
I have 2 tables like this:
Table person
id | name
---------
1 | john
2 | mike
3 | carl
4 | keny
5 | anna
Table vehicle
owner | vechicle
----------------
1 | RTA457
3 | GSW684
3 | GKI321
3 | SNE798
5 | YTT662
So, I want to make a query joining both tables, something like this:
SELECT * FROM person LEFT JOIN vehicle ON person.id=vehicle.owner
Getting these results
id | name | owner | vechicle
----------------------------
1 | john | 1 | RTA457
2 | mike | NULL | NULL
3 | carl | 3 | GSW684
3 | carl | 3 | GKI321
3 | carl | 3 | SNE798
4 | keny | NULL | NULL
5 | anna | 5 | YTT662
Finally, I want to limit it to 3 persons, showing all their vehicles, like this:
id | name | owner | vechicle
----------------------------
1 | john | 1 | RTA457
2 | mike | NULL | NULL
3 | carl | 3 | GSW684
3 | carl | 3 | GKI321
3 | carl | 3 | SNE798
There is any way to do it?
May help with a subquery
SELECT
*
FROM
(SELECT * FROM person LIMIT 3) t
LEFT JOIN vehicle ON t.id = vehicle.owner
Didn't try it, but something like this:
SELECT * FROM person
LEFT JOIN vehicle ON person.id = vehicle.owner
WHERE person.id IN (SELECT ID FROM PERSON LIMIT 3);
You could simply have your query as such:
SELECT * FROM person LEFT JOIN vehicle ON person.id=vehicle.owner LIMIT 10;
This SO could be handy as well. Hope this helps!
I am trying to join 3 tables and get counts of each contact's cases. So far I have this query written, but the result shows me contacts who has cases. I'd like to have a new column where it would show me "No of cases" for each contact, so the result should be 3 rows, 3 columns (last column is counts of cases)
Table A (Contacts)
+-----------------------+----+---------------------------------+
| Name | id | Organization |
+-----------------------+----+---------------------------------+
| Heidi Wilson-Reynolds | 2 | Alabama Arts Services |
+-----------------------+----+---------------------------------+
| Dr. Andrew Zope | 3 | Connecticut Empowerment Academy |
+-----------------------+----+---------------------------------+
| Rolando Cooper Sr. | 8 | Dutton Advocacy Trust |
+-----------------------+----+---------------------------------+
Table B (Case Contacts)
+----+---------+------------+
| id | case_id | contact_id |
+----+---------+------------+
| 1 | 1 | 2 |
+----+---------+------------+
| 2 | 2 | 3 |
+----+---------+------------+
| 3 | 3 | 8 |
+----+---------+------------+
| 4 | 4 | 2 |
+----+---------+------------+
| 5 | 5 | 3 |
+----+---------+------------+
| 6 | 6 | 8 |
+----+---------+------------+
Table C (Cases)
+----+-----------+
| id | status_id |
+----+-----------+
| 1 | 1 |
+----+-----------+
| 2 | 1 |
+----+-----------+
| 3 | 1 |
+----+-----------+
| 4 | 1 |
+----+-----------+
| 5 | 1 |
+----+-----------+
| 6 | 1 |
+----+-----------+
Query:
SELECT
A.display_name AS 'Name',
A.organization_name AS 'Organization'
FROM
A
INNER JOIN
B ON A.id = B.contact_id
INNER JOIN
C ON B.case_id = C.id
WHERE
A.contact_type = 'Individual' and C.status_id = 1; # Case status 1 is "Ongoing"
Result:
+-----------------------+---------------------------------+
| Name | Organization |
+-----------------------+---------------------------------+
| Heidi Wilson-Reynolds | Alabama Arts Services |
+-----------------------+---------------------------------+
| Dr. Andrew Zope | Connecticut Empowerment Academy |
+-----------------------+---------------------------------+
| Rolando Cooper Sr. | Dutton Advocacy Trust |
+-----------------------+---------------------------------+
| Heidi Wilson-Reynolds | Alabama Arts Services |
+-----------------------+---------------------------------+
| Dr. Andrew Zope | Connecticut Empowerment Academy |
+-----------------------+---------------------------------+
| Rolando Cooper Sr. | Dutton Advocacy Trust |
+-----------------------+---------------------------------+
This is the result I would like it to show, I think I need to use COUNT() function:
+-----------------------+---------------------------------+-----------------+
| Name | Organization | number_of_cases |
+-----------------------+---------------------------------+-----------------+
| Heidi Wilson-Reynolds | Alabama Arts Services | 2 |
+-----------------------+---------------------------------+-----------------+
| Dr. Andrew Zope | Connecticut Empowerment Academy | 2 |
+-----------------------+---------------------------------+-----------------+
| Rolando Cooper Sr. | Dutton Advocacy Trust | 2 |
+-----------------------+---------------------------------+-----------------+
Use group by
SELECT
A.display_name AS 'Name',
A.organization_name AS 'Organization',
count(*) AS 'number_of_cases'
FROM
A
INNER JOIN
B ON A.id = B.contact_id
INNER JOIN
C ON B.case_id = C.id
WHERE
A.contact_type = 'Individual' and C.status_id = 1; # Case status 1 is "Ongoing"
GROUP BY A.display_name, A.organization_name
The count(*) count the number of row that match the same value for the grouped by column .. in your case you have three distinct value for (name, Organization)
the the group by clause return this three different rows .. ad for each of this row count the number of rows that have the same value for name and Organization.
In you sample all the three value for (name, Organization) have 2 rows each ..
see this for brief tutorial for aggregation function
http://www.w3schools.com/sql/sql_functions.asp
http://www.sql-tutorial.com/sql-aggregate-functions-sql-tutorial/
Use GROUP BY NAME, ORGANIZATION and count the results using the output of this query. Basically you can include this output in another SELECT statement to get desired result
I'm new to relational sql. I'm trying to figure out a query to return the names of customers who have more than one type of account.
customers:
+------------+--------------+
| cid | Name |
+------------+--------------+
| 1 | Bob |
| 2 | John |
| 3 | Jane |
+------------+--------------+
accounts:
+------------+--------------+
| aid | type |
+------------+--------------+
| 1 | Checking |
| 2 | Saving |
| 3 | CD |
+------------+--------------+
transactions:
+------------+--------------+--------------+
| tid | cid | aid |
+------------+--------------+--------------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 1 | 2 |
| 4 | 2 | 3 |
| 5 | 3 | 1 |
+------------+--------------+--------------+
With these tables, the query should return Bob and John. I'm having some trouble with how to write such a query. More specifically, how do I keep count of how many accounts a customer has and how do I compare if the accounts are different without adding a new column to the table?
Okay, this seems to work in SQL Fiddle with my test data structure. Try it out with your real data structure and see if it gives you what you're looking for.
SELECT name FROM customers c WHERE EXISTS(
SELECT DISTINCT aid FROM transactions
WHERE cid = c.cid
HAVING COUNT(DISTINCT aid)>1
)