How to get name from another table when ids match? - mysql

Well, I suck in here (although I'm trying to learn). I can't understand how to improve my code when I see when others answer similar question to my (I know it might duplicate) and at the moment I'm stuck at my last step finishing php file. I have a tables called "cities" where there are columns called "id" and "name" and another table called "locations" where there are columns "id" and "location". I also have code:
$query = "SELECT * FROM locations";
$res = mysql_query($query);
while ($arr = mysql_fetch_array($res, MYSQL_ASSOC))
{
echo '<b>'.$arr['id'].'</b><b>'.$arr['location'].'</b>';
}
While my code works and I get id of wanted ID, I need to get name of city and not id. IDs in both tables match. I cannot edit tables or columns. What should I add? Can it be solved without any left, join, in, etc. queries? I can't understand them despite how I'm trying...

Try this out
$r = mysql_query("SELECT l.id, c.name
FROM locations AS l
INNER JOIN cities AS c ON c.id = l.id
");
while($l = mysql_fetch_array($r, MYSQL_ASSOC)){
echo '<b>' . $l['id'] .'</b><b>' . $l['name'] . '</b>';
}

Related

to merge 3 tables email field n check for existence of d same mail in registered user table

I want to merge 3 tables together and each has field named as email,all three tables emails has to merge in a single column and then this email need to check against registered user table for their existence.If existed then show all mail which are existing.i have tried but not getting a workable solution.
edit - editor attempted to reconstruct code from comments; looks like some things were lost.
Here is what I have tried so far:
SELECT GROUP_CONCAT(luckydraw_weekone.Email),
GROUP_CONCAT(luckydraw_weektwo.Email),
GROUP_CONCAT(participants.Email) FROM luckydraw_weekone
LEFT JOIN luckydraw_weektwo ON luckydraw_weekone.id = luckydraw_weektwo.id
LEFT JOIN participants ON luckydraw_weekone.id = participants.id";
query for mergingtd>"; // and all details you want to add
$display_string_user .= "</tr>";
}
}
$display_string .= "</table>";
$display_string_user .= "</table>";
echo $display_string;
echo $display_string_user;
$query2 = "SELECT mail FROM users WHERE mail='.$row[0].' OR mail='.$row[1].' OR mail='.$row[2].'";
First query is to merge the three tables; and second one is to check for existing emails in user table. The second one is inside the while loop.
Try this:
SELECT DISTINCT u.mail
FROM users u
INNER JOIN (SELECT email FROM luckydraw_weekone
UNION
SELECT email FROM luckydraw_weektwo
UNION
SELECT email FROM participants
) AS A ON u.mail = A.email;

Join on field with comma delimited string

I want to join two tables based on comma seperated keys contained in one field. So the two tables are 'topic' and 'link' and topic contains the field 'links' which contains the comma seperated IDs of records in the table link. Is this possible?
While you should be more descriptive with your question (it would be nice to have table definitions, sample data, desired output), #AaronBertrand showed me this earlier today on how to join tables on comma separated lists:
SELECT DISTINCT T.Id, L.Link
FROM Topic T
JOIN Link L ON CONCAT(',',T.Links,',') LIKE CONCAT('%', L.Link,'%')
Here is some condensed SQL Fiddle to use as an example.
Good luck.
Thanks for this. After looking around a bit more I decided to create a third table called topic_lnks which contain seperate fields for the topic ID and the link ID. This will make the join much easier to handle. In my case I use:
if(isset($_POST['submit'])){
$query = "INSERT INTO topic (topic_pk,title,topic,majors,sub_discipline_fk,author_fk,created)
VALUES ('','$title','$topic','$majors_string','$sub_discipline','$author_pk',NOW())";
$result = mysql_query($query, $connection) or die(mysql_error());
if($result){
$topic_pk = mysql_insert_id();
}
foreach($links as $link){
$query_links = "INSERT INTO topic_links (topic_link_pk,topic_fk,link_fk)
VALUES ('','$topic_pk','$link')";
$result_links = mysql_query($query_links, $connection) or die(mysql_error());
}
if($result_links){
$message = "- The topic '" . $title . "' has been created";
}
}
Then I can just query the topic_links table getting links based on the field 'topic_fk'.

Per-row dynamic sql

I have a database representing something like a bookstore. There's a table containing the categories that books can be in. Some categories are defined simply using another table that contains the category-item relationships. But there are also some categories that can be defined programmatically -- a category for a specific author can be defined using a query (SELECT item_id FROM items WHERE author = "John Smith"). So my categories table has a "query" column; if it's not null, I use this to get the items in the category, otherwise I use the category_items table.
Currently, I have the application (PHP code) make this decision, but this means lots of separate queries when we iterate over all the categories. Is there some way to incorporate this dynamic SQL into a join? Something like:
SELECT c.category, IF(c.query IS NULL, count(i.items), count(EXECUTE c.query)
FROM categories c
LEFT OUTER JOIN category_items i
ON c.category = i.category
EXECUTE requires a prepared statement, but I need to prepare a different statement for each row. Also, EXECUTE can't be used in expressions, it's just a toplevel statement. Suggestions?
What happens when you want to list books by publisher? Country? Language? You'd have to throw them all into a single "category_items" table. How would you pick which dynamic query to execute? The query-within-a-query method is not going to work.
I think your concept of "category" is too broad, which is resulting in overly complicated SQL. I would replace "category" to represent only "genre" (for books). Genres are defined in their own table, and item_genres connects them to the items table. Books-by-author and books-by-genre should just be separate queries at the application level, rather than trying to do them both with the same (sort of) query at the database/SQL level. (If you have music as well as books, they probably shouldn't all be stored in a single "items" table because they're different concepts ... have different genres, author vs. artist, etc.)
I know this does not really solve your problem in the way you'd like, but I think you'll be happier not trying to do it that way.
Here's how I finally ended up solving this in the PHP client.
I decided to just keep the membership in the category_items table, and use the dynamic queries during submission to update this table.
This is the function in my script that's called to update an item's categories during submission or updating. It takes a list of user-selected categories (which can only be chosen from categories that don't have dynamic queries), and using this and the dynamic queries it figures out the difference between the categories that an item is currently in and the ones it should be in, and inserts/deletes as necessary to get them in sync. (Note that the actual table names in my DB are not the same as in my question, I was using somewhat generic terms.)
function update_item_categories($dbh, $id, $requested_cats) {
$data = mysql_check($dbh, mysqli_query($dbh, "select id, query from t_ld_categories where query is not null"), 'getting dynamic categories');
$clauses = array();
while ($row = mysqli_fetch_object($data))
$clauses[] = sprintf('select %d cat_id, (%d in (%s)) should_be_in',
$row->id, $id, $row->query);
if (!$requested_cats) $requested_cats[] = -1; // Dummy entry that never matches cat_id
$requested_cat_string = implode(', ', $requested_cats);
$clauses[] = "select c.id cat_id, (c.id in ($requested_cat_string)) should_be_in
from t_ld_categories c
where member_type = 'lessons' and query is null";
$subquery = implode("\nunion all\n", $clauses);
$query = "select c.cat_id cat_id, should_be_in, (member_id is not null) is_in
from ($subquery) c
left outer join t_ld_cat_members m
on c.cat_id = m.cat_id
and m.member_id = $id";
// printf("<pre>$query</pre>");
$data = mysql_check($dbh, mysqli_query($dbh, $query), 'getting current category membership');
$adds = array();
$deletes = array();
while ($row = mysqli_fetch_object($data)) {
if ($row->should_be_in && !$row->is_in) $adds[] = "({$row->cat_id}, $id)";
elseif (!$row->should_be_in && $row->is_in) $deletes[] = "(cat_id = {$row->cat_id} and member_id = $id)";
}
if ($deletes) {
$delete_string = implode(' or ', $deletes);
mysql_check($dbh, mysqli_query($dbh, "delete from t_ld_cat_members where $delete_string"), 'deleting old categories');
}
if ($adds) {
$add_string = implode(', ', $adds);
mysql_check($dbh, mysqli_query($dbh, "insert into t_ld_cat_members (cat_id, member_id) values $add_string"),
"adding new categories");
}
}

Brain boiling from MySQL - How to do a complicated select from multiple tables?

I have two tables: Users and Groups
In my table "Users", there is a column called "ID" for all the user ids.
In my table "Groups" there is a column called "Participants", fields in this column are filled with all the user ids like this "PID_134,PID_489,PID_4784," - And there is a column "ID" that identifies a specific group.
Now what i want to do, i want to create a menu that shows all the users that are not yet in this particular group.
So i need to get all the user ids, that are not yet in the Participants column of a group with a particular ID.
It would be cool if there was a single mysql query for that - But any PHP + MySQL solutions are okay, too.
How does that work? Any guesses?
UPDATE:
i know, that's not code, but is there a way I could do something like this that would return me a list of all the users?
SELECT *
FROM users, groups
WHERE groups.participants NOT LIKE '%PID_'users.id'%' AND groups.id = 1;
Something like this. You just get rid of "PID_" part of ID.
SELECT * FROM [users] WHERE [id] NOT IN
(SELECT replace(id,'PID_','') FROM groups WHERE group_name='group1')
Group1 would be your variable - group id/name of menu that you've opened.
You can select from multiple tables as shown below:
SELECT * from users, groups WHERE users.id != groups.participants AND groups.id = 1;
This will list all users who are not in group id 1; A more elegant solution can be found by using joins, but this is simple and will do the trick.
I believe something like that should help:
SELECT * FROM users WHERE users.id NOT IN (SELECT groups.participants FROM groups)
But this works only if your DB is normalized. So for your case I see only PHP + MySQL solution. Not very elegant, but it does the job.
<?php
$participants_array = mysql_query("SELECT participants FROM groups");
$ids = array();
while ($participant = mysql_fetch_assoc($participants_array))
{
$id = explode(',', $participant['participant']);
foreach ($id as $instance)
{
if (!in_array($instance, $ids)) $ids[] = $instance;
}
}
$participants = implode(',', $ids);
$result = mysql_query("SELECT * FROM users WHERE id NOT IN ( $participants )");
But I highly recommend normalizing the database.

unknown column in where clause

$result = mysql_query("SELECT * FROM Volunteers WHERE Volunteers.eventID = " . $var);
$sql = mysql_query("SELECT * FROM Members WHERE Members.pid = " . $temp);
I am also doing or die(mysql_error()) at the end of both statements if that matter. My problem is that the first statement executes perfectly but in that table I store an attribute called pid. So the second statement is supposed to take that and return the row where it equals that pid so I can get the name. I get an error that says unknown column in 'a2' in 'where clause' where a2 the pid attribute returned from the first statement. Thanks for any help!
EDIT: Figured out what was wrong.
Had to write the code like this:
$sql = mysql_query("SELECT * FROM Members WHERE Members.pid = '$temp'") or die(mysql_error());
I think I see what you are trying to do, you can do this in one query, by JOIN-ing the tables together. the SQL query should be something like
SELECT Members.* FROM Members INNER JOIN Volunteers ON Volunteers.eventID=Members.pid WHERE Volunteers.eventID=" . $var
Check out This for a basic introduction to SQL joins.