4

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?

Bill Karwin
  • 538,548
  • 86
  • 673
  • 828
Brian
  • 26,662
  • 52
  • 135
  • 170

1 Answers1

5
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
  • 538,548
  • 86
  • 673
  • 828
  • Note that all the queries are from the same Table, how would I deal with that? – Brian Jan 05 '10 at 01:59
  • 1
    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 Jan 05 '10 at 02:03
  • 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 Jan 05 '10 at 02:50
  • 1
    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 - Слава Україні Jan 05 '10 at 02:55
  • @Bob Jarvis: MySQL does not support `INTERSECT`. – Bill Karwin Jan 05 '10 at 02:58
  • 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 Jan 05 '10 at 03:58
  • 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 Jan 06 '10 at 05:28
  • 1
    Can you use `EXPLAIN` to get an optimizer report? You probably need a compound index either on `(Title, Variable)` or `(Location, Date)`. – Bill Karwin Jan 06 '10 at 05:42
  • 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 Jan 06 '10 at 06:24
  • 1
    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 Jan 06 '10 at 07:29