Got following Tables in my SQL-Database (simplified):
Table Blogs:
+----+----------------------+----------+
| ID | Date | TitleGer |
+----+----------------------+----------+
| 1 | 2017-04-28 15:09:46 | Huhu |
| 2 | 2017-04-28 15:16:18 | Miau |
| 3 | 2017-04-28 15:17:14 | Kleff |
+----+----------------------+----------+
Table PicturesJoin:
+-------------+---------+---------------------+
| IDPicture | IDBlog | Date |
+-------------+---------+---------------------+
| 86 | 1 | 2017-06-28 17:41:11 |
| 87 | 1 | 2017-06-28 17:41:11 |
+-------------+---------+---------------------+
Table Pictures:
+------+-------------------------+---------------------+
| ID | Filename | Date |
+------+-------------------------+---------------------+
| 86 | 20170512200326_320.jpg | 2017-05-12 20:03:26 |
| 87 | 20170512200326_384.jpg | 2017-05-12 20:03:30 |
+------+-------------------------+---------------------+
PictureJoin "joins" the Picture with the Blog-Table. Now I use following SQL-Command to joine these two Tables (Blog - PictureJoin) / (PictureJoin - Pictures) together.
SELECT
Blogs.ID,
Blogs.Date,
TitleGer,
Pictures.Filename
FROM
Blogs
LEFT JOIN
PicturesJoin ON PicturesJoin.IDBlog = Blogs.ID
LEFT JOIN
Pictures ON Pictures.ID = PicturesJoin.IDPicture
ORDER BY
DATE DESC
The result might look like that:
+------+----------------------+-----------+------------------------+
| ID | Date | TitleGer | Filename |
+------+----------------------+-----------+------------------------+
| 1 | 2017-06-28 15:09:46 | Huhu | 20170512200326_320.jpg |
| 1 | 2017-06-28 15:09:46 | Huhu | 20170512200326_384.jpg |
| 2 | 2017-04-28 15:16:18 | Miau | NULL |
| 3 | 2017-04-28 15:17:14 | Kleff | NULL |
+------+----------------------+-----------+------------------------+
He makes a cross-product out of the available Pictures, which is also logical. But I want him to just use the first Picture he finds. In the end it should look like that:
+------+----------------------+-----------+------------------------+
| ID | Date | TitleGer | Filename |
+------+----------------------+-----------+------------------------+
| 1 | 2017-06-28 15:09:46 | Huhu | 20170512200326_320.jpg |
| 2 | 2017-04-28 15:16:18 | Miau | NULL |
| 3 | 2017-04-28 15:17:14 | Kleff | NULL |
+------+----------------------+-----------+------------------------+
Tried several hours but couldn't get it to work. Please help!
The easiest approach may be to select one IDPicture per IDBlog from PicturesJoin only:
SELECT
b.ID,
b.Date,
b.TitleGer,
p.Filename
FROM Blogs b
LEFT JOIN
(
SELECT
IDBlog,
MIN(IDPicture) AS IDPicture
FROM PicturesJoin
GROUP BY IDBlog
) pj ON pj.IDBlog = b.ID
LEFT JOIN Pictures p ON p.ID = pj.IDPicture
ORDER BY b.Date DESC;
SELECT b.ID,b.Date,b.TitleGer,p.Filename
FROM Blogs b
LEFT JOIN
(
SELECT main_table.*
FROM PicturesJoin main_table LEFT JOIN PicturesJoin child_table
ON (main_table.IDBlog= child_table.IDBlog AND main_table.IDPicture> child_table.IDPicture)
WHERE child_table.id IS NULL
)
OUTER_TABLE ON OUTER_TABLE .IDBlog = b.ID
LEFT JOIN Pictures p ON p.ID = pj.IDPicture
ORDER BY b.Date DESC;
Try above query.
Related
I have 3 tables:
applications (has many votes)
votes (belongs to applications and questions)
questions (has many votes)
I need to get number of votes per application per question.
So, my attempt was:
SELECT applications.id, COUNT(votes.id), votes.question_id
FROM applications
LEFT OUTER JOIN votes ON (votes.application_id = application.id)
GROUP BY votes.question_id
However, it displays data only for a single application, so I assume my query is malformed:
+----+-----------------+-------------+
| id | COUNT(votes.id) | question_id |
+----+-----------------+-------------+
| 1 | 1185 | 1 |
| 1 | 1170 | 2 |
| 1 | 1209 | 3 |
| 1 | 1230 | 4 |
| 1 | 1213 | 5 |
+----+-----------------+-------------+
What I need:
+----+-----------------+-------------+
| id | COUNT(votes.id) | question_id |
+----+-----------------+-------------+
| 1 | 1185 | 1 |
| 1 | 1170 | 2 |
| 1 | 1209 | 3 |
| 1 | 1230 | 4 |
| 1 | 1213 | 5 |
| 2 | null | 1 |
| 2 | 50 | 2 |
| 2 | 333 | 3 |
| 2 | 1230 | 4 |
| 2 | 1213 | 5 |
| 3 | null | 1 |
| 3 | 50 | 2 |
| 3 | 333 | 3 |
| 3 | null | 4 |
| 3 | 5555 | 5 |
+----+-----------------+-------------+
The group by clause was missing applications.id.
SELECT applications.id, COUNT(votes.id), votes.question_id
FROM applications
LEFT OUTER JOIN votes ON votes.application_id = application.id
group by applications.id, votes.question_id
You should be grouping by the applications.id as well as the questions.id:
SELECT a.id, COUNT(votes.id), votes.question_id
FROM applications a LEFT OUTER JOIN
votes v
ON v.application_id = a.id
GROUP BY a.id, v.question_id;
However, this will not produce exactly what you want. You seem to want all the questions for the applications, regardless of whether or not there are any votes. If so, this is probably what you want:
SELECT a.id, q.question_id, COUNT(v.application_id)
FROM applications a CROSS JOIN
(SELECT DISTINCT question_id FROM votes) q LEFT JOIN
votes v
ON v.application_id = a.id and v.question_id = q.question_id
GROPU BY a.id, q.question_id;
The result I want.
+--------+-------------+------------+--------+
| Tag | most_recent | Comment | Author |
+--------+-------------+------------+--------+
| TAG001 | 2015-07-23 | Something3 | AM |
| TAG002 | 2015-07-25 | Something5 | BN |
+--------+-------------+------------+--------+
The tables I have:
Status Table
+--------+-------------+------------+
| Tag | Status | DateStatus |
+--------+-------------+------------+
| TAG001 | Not Started | |
| TAG002 | Complete | 2015-07-23 |
+--------+-------------+------------+
Comments Table
+----+--------+-------------+------------+--------+
| ID | Tag | DateCreated | Comment | Author |
+----+--------+-------------+------------+--------+
| 1 | TAG001 | 2015-07-22 | Something1 | JS |
| 2 | TAG002 | 2015-07-23 | Something2 | JS |
| 3 | TAG001 | 2015-07-23 | Something3 | AM |
| 4 | TAG002 | 2015-07-23 | Something4 | AS |
| 5 | TAG002 | 2015-07-25 | Something5 | BN |
+----+--------+-------------+------------+--------+
I've tried 4 different queries, each getting progressively more complicated, but still not working.
The queries I have tried:
Query 1)
SELECT Comments.[Tag], Max(Comments.[DateCreated]) AS most\_recent
FROM Comments
GROUP BY Comments.[Tag];
Result 1)
+--------+-------------+
| Tag | most_recent |
+--------+-------------+
| TAG001 | 2015-07-23 |
| TAG002 | 2015-07-25 |
+--------+-------------+
Just gives me the most recent date, but no values.
Query 2)
SELECT Comments.[Tag], Max(Comments.[DateCreated]) AS most\_recent
FROM Comments
GROUP BY Comments.[Tag];
Result 2)
+--------+-------------+------------+
| Tag | most_recent | Comment |
+--------+-------------+------------+
| TAG001 | 2015-07-22 | Something1 |
| TAG001 | 2015-07-23 | Something3 |
| TAG002 | 2015-07-23 | Something2 |
| TAG002 | 2015-07-23 | Something4 |
| TAG002 | 2015-07-25 | Something5 |
+--------+-------------+------------+
Now I see all the information I want, but I cannot filter for the most recent.
I tried DISTINCT, but it didn't work.
Query 3)
Modified from here: MYSQL - Join most recent matching record from one table to another
SELECT Status.\*,Comments.\*
FROM Status S
LEFT JOIN Comments C ON S.tag = C.tag
JOIN(SELECT x.tag, MAX(x.DateCreated) AS MaxCommentDate FROM Comments x
GROUP BY x.tag) y ON y.tag = x.tag AND y.MaxCommentDate = x.DateCreated
Result: Syntax error (missing operator) in query expression
Query 4)
Modified from here:
Left Join to most recent record
SELECT
Status.\*,Comments.\*
FROM Status S
LEFT JOIN
(
Comments C
INNER JOIN
(
SELECT
x.tag, MAX(x.DateCreated) AS MaxCommentDate
FROM
Comments x
GROUP BY
x.tag
)
y
ON y.tag = x.tag
AND y.MaxCommentDate = x.DateCreated
)
ON S.tag = C.tag;
Result: Syntax Error on JOIN
Not having much luck...thanks in advanced.
Thanks.
The following seems to work for me in Access 2010:
SELECT c.Tag, c.DateCreated AS most_recent, c.Comment, c.Author
FROM
(
SELECT Tag, MAX(DateCreated) AS MaxDate
FROM Comments
GROUP BY Tag
) AS md
INNER JOIN
Comments AS c
ON c.Tag = md.Tag AND c.DateCreated = md.MaxDate
I have 3 table
major table:
+----+------------+
| id | major |
+----+------------+
| 1 | Computer |
| 2 | Architect |
| 3 | Designer |
+----+------------+
classroom table:
+----+----------+-------+
| id | major_id | name |
+----+----------+-------+
| 1 | 1 | A |
| 2 | 1 | B |
| 3 | 1 | C |
| 4 | 2 | A |
| 5 | 2 | B |
| 6 | 3 | A |
+----+----------+-------+
and finally, student_classroom table
+----+------------+--------------+----------+
| id | student | classroom_id | status |
+----+------------+--------------+----------+
| 1 | John | 1 | Inactive |
| 2 | Defou | 2 | Active |
| 3 | John | 2 | Active |
| 4 | Alexa | 1 | Active |
| 5 | Nina | 1 | Active |
+----+------------+--------------+----------+
how can I use propel to build query below
select
a.id,
a.major,
b.number_of_student,
c.number_of_classroom
from major a
left join (
select
major.major_id,
count(student_classroom.id) as number_of_student
from major
left join classroom on classroom.major_id = major.id
left join student_classroom on student_classroom.classroom_id = classroom.id
where student_classroom.`status` = 'Active'
group by major_id
) b on b.major_id = a.major_id
left join (
select
major.major_id,
count(classroom.id) as number_of_classroom
from major
left join classroom on classroom.major_id = major.id
group by major_id
) c on c.major_id = a.major_id
Because I want the final result would be something like this, I spend hours trying to figure it out without success.
+----+------------+-------------------+---------------------+
| id | major | number_of_student | number_of_classroom |
+----+------------+-------------------+---------------------+
| 1 | Computer | 4 | 3 |
| 2 | Architect | 0 | 2 |
| 3 | Designer | 0 | 1 |
+----+------------+-------------------+---------------------+
Try this
select
m.id,
m.major,
count(distinct s.id) as number_of_student ,
count(distinct c.id) as number_of_classroom
from major m
left join classroom c on
(m.id = c.major_id)
left join student_classroom s
on (s.classroom_id = c.id and c.major_id = m.id and s.status = 'active')
group by m.id
order by m.id
I have 3 tables to join and need some help to make it work, this is my schema:
donations:
+--------------------+------------+
| uid | amount | date |
+---------+----------+------------+
| 1 | 20 | 2013-10-10 |
| 2 | 5 | 2013-10-03 |
| 2 | 50 | 2013-09-25 |
| 2 | 5 | 2013-10-01 |
+---------+----------+------------+
users:
+----+------------+
| id | username |
+----+------------+
| 1 | rob |
| 2 | mike |
+----+------------+
causes:
+--------------------+------------+
| id | uid | cause | <missing cid (cause id)
+---------+----------+------------+
| 1 | 1 | stop war |
| 2 | 2 | love |
| 3 | 2 | hate |
| 4 | 2 | love |
+---------+----------+------------+
Result I want (data cropped for reading purposes)
+---------+-------------+---------+-------------+
| id | username | amount | cause |
+---------+-------------+---------+-------------+
| 1 | rob | 20 | stop war |
| 2 | mike | 5 | love |
+---------+-------------+-----------------------+
etc...
This is my current query, but returns double data:
SELECT i.*, t.cause as tag_name
FROM users i
INNER JOIN donations tti ON (tti.uid = i.id)
INNER JOIN causes t ON (t.uid = tti.uid)
EDIT: fixed sql schema on fiddle
http://sqlfiddle.com/#!2/0e06c/1 schema and data
How I can do this?
It seems your table's model is not right. There should be a relation between the Causes and Donations.
If not when you do your joins you will get duplicated rows.
For instance. Your model could look like this:
Donations
+--------------------+------------+
| uid | amount | date | causeId
+---------+----------+------------+
| 1 | 20 | 2013-10-10 | 1
| 2 | 5 | 2013-10-03 | 2
| 2 | 50 | 2013-09-25 | 3
| 2 | 5 | 2013-10-01 | 2
+---------+----------+------------+
causes:
+----------------------+
| id | cause |
+---------+------------+
| 1 | stop war |
| 2 | love |
| 3 | hate |
+---------+------------+
And the right query then should be this
SELECT i.*, t.cause as tag_name
FROM users i
INNER JOIN donations tti ON (tti.uid = i.id)
INNER JOIN causes t ON (t.id = tti.causeId)
Try this
SELECT CONCAT(i.username ,' ',i.first_name) `name`,
SUM(tti.amount),
t.cause AS tag_name
FROM users i
LEFT JOIN donations tti ON (tti.uid = i.id)
INNER JOIN causes t ON (t.uid = tti.uid)
GROUP BY i.id
Fiddle
You need to match the id from both the users and causes table at the same time, like so:
SELECT i.*, t.cause as tag_name
FROM users i
INNER JOIN donations tti ON (tti.uid = i.id)
INNER JOIN causes t ON (t.uid = tti.uid and t.id = i.id)
Apologies for formatting, I'm typing this on a phone.
I have two tables like this
profile_answers
+---------+------------+
| id | class_name |
+---------+------------+
| 1 | Class 1 |
| 2 | Class 2 |
| 3 | Class 1 |
+---------+------------+
educations
+---------+--------------------+------------+
| id | profile_answers_id | sample |
+---------+--------------------+------------+
| 1 | 1 | 1234 |
| 2 | 1 | 2334 |
| 3 | 1 | 3434 |
+---------+------------+--------------------+
I ran the query,
select educations.profile_answer_id, GROUP_CONCAT(educations.sample) from educations
LEFT JOIN profile_answers ON educations.profile_answers_id = profile_answers.id
I got
+--------+--------------------+-------------+
| id | sample |
+---------+--------------------+------------+
| 1 | 1234,2334,3434 |
+---------+------------+--------------------+
I actually want,
+--------+--------------------+-------------+
| id | sample |
+---------+--------------------+------------+
| 1 | 1234,2334,3434 |
| 2 | NULL |
| 3 | NULL |
+---------+------------+--------------------+
SELECT id,IFNULL(samples,'NULL') sample FROM
(
SELECT
AA.id,
GROUP_CONCAT(DISTINCT BB.sample) samples
FROM
profile_answers AA LEFT JOIN educations BB
ON AA.id = BB.profile_answers_id
GROUP BY AA.id
) A;
Looks like you're missing your GROUP BY:
select profile_answers.id, GROUP_CONCAT(educations.sample)
from profile_answers
LEFT JOIN educations ON educations.profile_answers_id = profile_answers.id
GROUP BY profile_answers.id
I also altered your JOIN to make the profile_answers table your main table.
Good luck.