tags:

views:

69

answers:

1

I have the following query using INTERSECT and I can't figure out how to translate it to MySQL using INNER JOIN.

SELECT DISTINCT Title, Variable FROM Table WHERE Location='Location1' AND Date='Date1'  
INTERSECT  
SELECT DISTINCT Title, Variable FROM Table WHERE Location='Location2' AND Date='Date2'  
INTERSECT  
SELECT DISTINCT Title, Variable FROM Table WHERE Location='Location3' AND Date='Date3'

Can anyone give me a hand?

+2  A: 
SELECT t1.Title, t1.Variable
FROM Table t1
JOIN Table t2 USING (Title, Variable)
JOIN Table t3 USING (Title, Variable)
WHERE (t1.Location, t1.Date) = ('Location1', 'Date1')
  AND (t2.Location, t2.Date) = ('Location2', 'Date2')
  AND (t3.Location, t3.Date) = ('Location3', 'Date3');

You might need to use SELECT DISTINCT but I can't tell because I don't know your table structure, unique constraints, etc.


Re your cryptic comment: I tried the following script in my test database:

DROP TABLE IF EXISTS MyTable;
CREATE TABLE MyTable (
 id       SERIAL PRIMARY KEY,
 title    VARCHAR(20) NOT NULL,
 variable VARCHAR(20) NOT NULL,
 location VARCHAR(20) NOT NULL,
 date     DATE NOT NULL
);

INSERT INTO MyTable VALUES
 (DEFAULT, 'A Tale of Two Cities', 'variable', 'America', '2010-01-01'),
 (DEFAULT, 'A Tale of Two Cities', 'variable', 'England', '2010-02-01'),
 (DEFAULT, 'A Tale of Two Cities', 'variable', 'France',  '2010-03-01');

SELECT t1.Title, t1.Variable
FROM MyTable t1
JOIN MyTable t2 USING (Title, Variable)
JOIN MyTable t3 USING (Title, Variable)
WHERE (t1.Location, t1.Date) = ('America', '2010-01-01')
  AND (t2.Location, t2.Date) = ('England', '2010-02-01')
  AND (t3.Location, t3.Date) = ('France',  '2010-03-01');

The output is this:

+----------------------+----------+
| Title                | Variable |
+----------------------+----------+
| A Tale of Two Cities | variable |
+----------------------+----------+
Bill Karwin
Note that all the queries are from the same Table, how would I deal with that?
Brian
Right; I'm showing a self-join in the example above. You can use "Table" three times in a single query, and give each instance a distinct *table alias* so you can reference columns from each respective instance.
Bill Karwin
Huh, I followed that model and it still won't work
Brian
You're going to have to be more specific than that about what you tried and what didn't work. Did it give an error? Did it return no rows?
Bill Karwin
Is the INTERSECT version of the query working? Because I'd sure expect @Bill's version to produce the same results. An INTERSECT is similar to a UNION, but where a UNION links together the queries using OR logic, and INTERSECT uses an AND. So INTERSECT and INNER JOIN are very similar, in that both require results to be present from both queries for the values to be included in the final results.
Bob Jarvis
@Bob Jarvis: MySQL does not support `INTERSECT`.
Bill Karwin
sorry, this was my first time using table aliases and I didn't use the syntax properly and got an error message. Now I got it working. Thanks!
Brian
Does anyone have any advice for speeding up this query? I added a index for Location and Date, but it still takes over 10 seconds despite there only being 600,000 rows in my table.
Brian
Can you use `EXPLAIN` to get an optimizer report? You probably need a compound index either on `(Title, Variable)` or `(Location, Date)`.
Bill Karwin
I added a (Location, Date) index, but that's caused me to get error #126 - Incorrect key file for table. This is really weird, because it stays there even if I delete the key. Even more interesting, the error goes away if I remove both the `JOIN MyTable t3 USING (Title, Variable)` and the `AND (t3.Location, t3.Date) = ('France', '2010-03-01')` parts of the query
Brian
I just googled for that error, and it sounds like it indicates a corrupted index. You can try `REPAIR TABLE` to rebuild the index. See http://dev.mysql.com/doc/refman/5.1/en/myisam-repair.html
Bill Karwin