I have 2 tables, transactions and identifiers. Each transaction has a user_id, and each user_id can have multiple identifiers e.g.
transactions
user_id | amount | timestamp
12 10.00 1234567890
17 5.00 1234567890
12 7.00 1234567890
3 2.50 1234567890
identifiers
identifier | user_id
AEFT67 12
JHDASJK 12
KJSIDJ6 3
LKSDLK 5
HSDJH8 17
IUSDI5 17
I'd like to get a result like this:
result:
user_id | identifier | amount | timestamp
12 AEFT67 10.00 1234567890
17 HSDJH8 5.00 1234567890
12 AEFT67 7.00 1234567890
3 KJSIDJ6 2.50 1234567890
Both tables have many millions of rows and its important that I don't get duplicates when using a join (otherwise the amounts will be wrong).
I originally tried:
SELECT t.user_id, t.amount, i.identifier
FROM transactions AS t
LEFT JOIN identifiers AS i ON i.id = (
SELECT
i2.id
FROM identifiers i2
WHERE i2.user_id = t.user_id
LIMIT 1
)
WHERE t.timestamp BETWEEN 1234567890 AND 1234567890
Note - I don't actually mind which identifer I get for a user, but a user could have many. The nested JOIN is very slow (about 40sec) though on large datasets so I tried:
SELECT t1.user_id, t1.amount, i1.identifier FROM
(SELECT *
FROM transactions as t
WHERE t.timestamp BETWEEN 1234567890 AND 1234567890) as t1
LEFT JOIN
(SELECT * FROM identifiers GROUP BY user_id) i1
ON i1.user_id =t1.user_id
This actually cut the times down in half, but still very slow.
I feel like I'm missing something obvious, in each case I am searching through a lot of data in the identifiers table which is slowing it down (millions of rows rather than the 1000 or so needed). I feel that if I was able to use the result of the first query as a parameter in the second it would be much faster i.e.:
SELECT * FROM
(SELECT *
FROM transactions
WHERE t.timestamp BETWEEN 1234567890 AND 1234567890) as t1
LEFT JOIN
(SELECT * FROM identifiers WHERE user_id in (t1.user_id))
Is there a better way to get my filtered transactions with a reference to a single (any) identifier?
EDIT: Here's an sql fiddle set up: http://sqlfiddle.com/#!9/ecad23/6
EDIT2: For further clarification, I need to maintain a record of every single transaction, so the number of rows returned should be exactly what you'd expect if the where query was only applied to transactions table. Users can have multiple transactions so grouping a final result won't work