Reputation: 6980
I have joined together several tables to get data i want but since I am new to SQL i can't figure out how to stop data being returned more than once.
her's the SQL statement;
SELECT
T.url,
T.ID,
S.status,
S.ID,
E.action,
E.ID,
E.timestamp
FROM tracks T, status S, events E
WHERE S.ID AND T.ID = E.ID
ORDER BY E.timestamp DESC
The data that is returned is something like this;
+----------------------------------------------------------------+
| URL | ID | Status | ID | action | ID | timestamp |
+----------------------------------------------------------------+
| T.1 | 4 | hello | 4 | has uploaded a track | 4 | time |
| T.2 | 3 | bye | 3 | has some news | 3 | time |
| t.1 | 4 | more | 4 | has some news | 4 | time |
+----------------------------------------------------------------+
That's a very basic example but does outline what happens. If you look at the third row the URL is repeated when there is a different status.
This is what I want to happen;
+-------------------------------------------------------+
| URL or Status | ID | action | timestamp |
+-------------------------------------------------------+
| T.1 | 4 | has uploaded a track | time |
| hello | 3 | has some news | time |
| bye | 4 | has some news | time |
+-------------------------------------------------------+
Please notice that the the url (in this case the mock one is T.1) is shown when the action is has uploaded a track. This is very important. The action in the events table is inserted on trigger of a status or track insert. If a new track is inserted the action is 'has uploaded a track' and you guess what it is for a status. The ID and timestamp is also inserted into the events table at this point.
Note: There are more tables that go into the query, 3 more in fact, but I have left them out for simplicity.
Upvotes: 1
Views: 4609
Reputation: 6980
Thanks for all the answers, they helped a lot. I have made a query that works and manipulated the outcome with if statements in PHP.
Here it is;
SELECT
T.url AS track_url,
S.status,
E.action,
E.ID,
E.timestamp,
A.name,
A.url AS artist_url
FROM events E
LEFT JOIN
TRACKS T
ON T.ID = E.ID AND E.action = 'has uploaded a track.'
LEFT JOIN
STATUS S
ON S.ID = E.ID AND E.action = 'has some news.'
LEFT JOIN
ARTISTS A
ON A.ID = E.ID
ORDER BY E.timestamp DESC
The outcome of it is lots of NULL
columns but that's fine as it works! IF the ID
hasn't uploaded a track the relevant columns are NULL
and the same applies to the other bits of the query. The ID
is not repeated as only the ID
in the events table is selected.
If you see any problems that I may have overlooked please shout about it!
Upvotes: 0
Reputation: 34063
Change this
WHERE S.ID AND T.ID = E.ID
To this
WHERE S.ID = E.ID AND T.ID = E.ID
Update
There are some individuals that are extremely touchy feely about using implicit join notation. To appease these individuals and as better practice, you should use explicit JOIN
statements.
Upvotes: 0
Reputation: 1
try using group by;
SELECT T1.url, T1.id, S1.estatus, S1.id, E1.action, E1.id, E1.timestamp FROM t T1, s S1, e E1 WHERE S1.id AND T1.id = E1.id GROUP BY S1.id ORDER BY E1.timestamp DESC;
Upvotes: 0
Reputation: 86775
Don't use 20 year out of date syntax. Although many RDBMS support FROM a, b, c
style syntax it has been deprecated by all systems that I've worked with. (I haven't worked with everything, but it's really strongly advisable to not use this style.)
Instead use ANSI-92 standard JOIN
syntax. Then it's much harder to get things wrong...
SELECT
*
FROM
status S
INNER JOIN
tracks T
ON T.ID = S.ID
INNER JOIN
events E
ON E.ID = S.ID
ORDER BY
E.timestamp DESC
Also, you example data suggest that you have the following in table S...
Status | ID
--------+----
hello | 4
bye | 3
more | 4
ID = 4
has two rows. If you really want each row in T to only join on one row in S, which row should you pick? Should one be deleted, or do you have some other logic/condition that you can use to pick one of the two?
Upvotes: 2