[Dbix-class] JOIN question
Bernhard Graf
dbic2 at augensalat.de
Thu Nov 30 10:07:13 GMT 2006
Jess Robinson wrote:
> I'm attempting to follow this, and I'm still not convinced.. Can you
> toss out an example with actual data, show what rows your query
> produces, and what Matt's gets? I also think its possible without
> better JOIN conds..
See the example in the first email in this thread.
You can c&p them in a MySQL-db, for example the test-db, that is there by default on first install.
The first email (email.id=1) has only on text part.
Second email (email.id=2) is HTML-only.
Third (email.id=3) is multipart, Text+HTML.
Now my query to find all emails that have only a text part
mysql> SELECT me.id,me.title
FROM email me
LEFT JOIN chunk chunks ON chunks.email=me.id
LEFT JOIN chunk chunks_2 ON chunks_2.email=me.id
AND chunks.id!=chunks_2.id
WHERE chunks.mimetype='text/plain'
AND chunks_2.mimetype IS NULL:
+----+------------+
| id | title |
+----+------------+
| 1 | plain text |
+----+------------+
Matt proposes
WHERE (chunks.id IS NULL OR chunks_2.id IS NULL OR chunks.id != chunks_2.id)
I suppose to find the text-only email, he would suggest:
mysql> SELECT me.id,me.title
FROM email me
LEFT JOIN chunk chunks ON chunks.email=me.id
LEFT JOIN chunk chunks_2 ON chunks_2.email=me.id
WHERE (chunks.id IS NULL
OR chunks_2.id IS NULL
OR chunks.id != chunks_2.id)
AND chunks.mimetype='text/plain';
+----+-----------+
| id | title |
+----+-----------+
| 3 | text+html |
+----+-----------+
This can't work, because "WHERE chunks.id != chunks_2.id" removes all
lines that find emails that are only text or html; both "... IS NULL"
statements are always false.
To give a better understanding you can output all combinations:
mysql> SELECT me.id,me.title,
chunks.id,chunks.mimetype,
chunks_2.id,chunks_2.mimetype
FROM email me
LEFT JOIN chunk chunks ON chunks.email=me.id
LEFT JOIN chunk chunks_2 ON chunks_2.email=me.id;
+----+------------+------+------------+------+------------+
| id | title | id | mimetype | id | mimetype |
+----+------------+------+------------+------+------------+
| 1 | plain text | 1 | text/plain | 1 | text/plain |
| 2 | plain html | 2 | text/html | 2 | text/html |
| 3 | text+html | 3 | text/plain | 3 | text/plain |
| 3 | text+html | 3 | text/plain | 4 | text/html |
| 3 | text+html | 4 | text/html | 3 | text/plain |
| 3 | text+html | 4 | text/html | 4 | text/html |
+----+------------+------+------------+------+------------+
See what remains with "WHERE chunks.id != chunks_2.id":
mysql> SELECT me.id,me.title,
chunks.id,chunks.mimetype,
chunks_2.id,chunks_2.mimetype
FROM email me
LEFT JOIN chunk chunks ON chunks.email=me.id
LEFT JOIN chunk chunks_2 ON chunks_2.email=me.id
WHERE chunks.id!=chunks_2.id;
+----+-----------+------+------------+------+------------+
| id | title | id | mimetype | id | mimetype |
+----+-----------+------+------------+------+------------+
| 3 | text+html | 4 | text/html | 3 | text/plain |
| 3 | text+html | 3 | text/plain | 4 | text/html |
+----+-----------+------+------------+------+------------+
Now the same with chunks.id != chunks_2.id in LEFT JOIN:
mysql> SELECT me.id,me.title,
chunks.id,chunks.mimetype,
chunks_2.id,chunks_2.mimetype
FROM email me
LEFT JOIN chunk chunks ON chunks.email=me.id
LEFT JOIN chunk chunks_2 ON chunks_2.email=me.id
AND chunks.id!=chunks_2.id;
+----+------------+------+------------+------+------------+
| id | title | id | mimetype | id | mimetype |
+----+------------+------+------------+------+------------+
| 1 | plain text | 1 | text/plain | NULL | NULL |
| 2 | plain html | 2 | text/html | NULL | NULL |
| 3 | text+html | 3 | text/plain | 4 | text/html |
| 3 | text+html | 4 | text/html | 3 | text/plain |
+----+------------+------+------------+------+------------+
Clear now?
--
Bernhard Graf
More information about the Dbix-class
mailing list