0

I'm trying to select all fields in two separate tables as long as they're sharing a common ID.

//mysql query
$result = mysql_query("SELECT * FROM project, links 
WHERE project.id = links.id and project.id = $clientID")

//displaying the link 
if ($row['url'] != null){
    echo "<div class='clientsection' id='links'>Links</div>";
    echo "<a class='clientlink' id='link1' href='" . $row['url'] . "'>" . $row['name'] . "</a>";
}
else {
echo "<a class='clientlink' id='link1' href='" . $row['url'] . "' style='display:none;'>" . $row['name'] . "</a>";
        };

As you can see, my tables are "projects", and "links" Each is sharing a common field "id" for reference. It looks as though where both links.id and project.id are equal, it outputs anything, but when there is no links.id associated with a given $clientID the container relative to the $clientID doesn't display at all.

Essentially I'm using this to add links dynamically to a specific client in this CMS and if there are no links, I want the container to show up anyway.

Hopefully I've expressed myself clearly, any pointers in the right direction are appreciated. Thanks!

2 Answers 2

5

Using the SQL ANSI explicit join syntax, you can specify a LEFT OUTER JOIN, as opposed to the INNER JOIN that you are doing in your implicit join.

The LEFT OUTER JOIN returns results in the first table even if there are no matching rows in the joining table:

SELECT * FROM project
LEFT OUTER JOIN links 
ON links.id = project.id
WHERE project.id = $clientID

For rows where there is no matching id in the links table, links.id will be NULL.

Edit

If you want just the first link, where the autoincrement primary key links.linkid specifies the order, you can do a self join like this:

SELECT * FROM project
LEFT OUTER JOIN links
ON links.id = project.id
LEFT OUTER JOIN links l2
ON l2.id = project.id AND l2.linkid < links.linkid
WHERE project.id = $clientID AND l2.id IS NULL

What this does is join in any links table rows where the linkid is smaller, and then exludes those rows in the WHERE clause. You end up with just the rows where there is no smaller linkid, hence the link with the smallest linkid for each project.

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks Marcus for your answer, although this has left me with something else to fix. Now, it is opening the correct containers, but on individual client IDs where there is more than one link, it displays multiple containers, with one showing the first link, and then another one created with each subsequent link
@Matt, is there a column in the links table that specifies the order of the links, so that we can find the "first" link?
I have a primary key, linkid that is obviously ordered, would that work?
@Matt, I've updated my answer for your second question. This can also be done with a sub query.
Hey Marcus, I really appreciate your time. I'm actually looking to display all the links, if there were 100 links for this $clientID i'd want to display all of them.. the edited query you posted actually causes zero links to display..
|
1

You're query is essentially doing an "INNER JOIN" so it will only return records where there is matching id's in both tables. If you do an "LEFT OUTER JOIN" as in Marcus's example it will return the results you are looking for.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.