When you join to tables together you need to think of it comparing each row from the first table to each row of the second table and then returning the ones that match based on the join condition. The join condition is specified in the ON
clause.
In almost all cases you want to reference both tables in the ON
clause. Let's look at your example in SQL Fiddle
MySQL 5.5.32 Schema Setup:
CREATE TABLE Question (
QID INT,
QTxt VARCHAR(150),
QOrder INT);
CREATE TABLE User (
UID INT,
UserName VARCHAR(150));
CREATE TABLE ANSWER (
AID INT,
ATxt VARCHAR(150),
QID INT,
USERID INT);
INSERT INTO User VALUES
(1, 'Alex'),
(2, 'Sarah'),
(3, 'Tom');
INSERT INTO Question VALUES
(1, 'Age', 1),
(2, 'Gender', 2),
(3, 'Weight',3),
(4, 'Height',4);
INSERT INTO Answer VALUES
(1, '30', 1 , 1),
(2, '27', 1,2),
(3, '30', 1,3),
(4, 'M', 2,1),
(5, 'F', 2,2),
(6, 'M', 2,3),
(7, '61', 4,1),
(8, '165', 3,1);
The ON
condition in your case is Answer.QID = Question.QID
:
Query 1:
SELECT *
FROM Answer
JOIN Question
ON Answer.QID = Question.QID
WHERE Answer.UserId = 3
Results:
| AID | ATXT | QID | USERID | QTXT | QORDER |
|-----|------|-----|--------|--------|--------|
| 3 | 30 | 1 | 3 | Age | 1 |
| 6 | M | 2 | 3 | Gender | 2 |
You can use aliases to shorten that query a little:
Query 2:
SELECT *
FROM Answer AS A
JOIN Question AS Q
ON A.QID = Q.QID
WHERE A.UserId = 3
Results:
| AID | ATXT | QID | USERID | QTXT | QORDER |
|-----|------|-----|--------|--------|--------|
| 3 | 30 | 1 | 3 | Age | 1 |
| 6 | M | 2 | 3 | Gender | 2 |
The same way you can now also join in the User
table:
Query 3:
SELECT *
FROM Answer AS A
JOIN Question AS Q
ON A.QID = Q.QID
JOIN User AS U
ON A.UserId = U.UID
WHERE U.UserName = 'Tom'
Results:
| AID | ATXT | QID | USERID | QTXT | QORDER | UID | USERNAME |
|-----|------|-----|--------|--------|--------|-----|----------|
| 3 | 30 | 1 | 3 | Age | 1 | 3 | Tom |
| 6 | M | 2 | 3 | Gender | 2 | 3 | Tom |
For more information on JOINs check out my JOIN series here: A Join a Day
It is written about Microsoft SQL Server, but most of it works in other database management system too.
Best Answer
You can do this:
Table1
is your base set, so join to it. You want to retain all values, so you use aLEFT JOIN
and you join on the matching task values. The group and count operations happen on different columns - theGROUP BY
is based on your tasks fromTable1
, and youCOUNT
the of tasks fromTable2
.Here's a demo (using
CTEs
as implemented by SQL Server, PostgreSQL, Oracle, etc.):