Getting both Id's from inner join - php

I am working on a website in the php Codeigniter framework, and am having problems with joining tables together.
The two tables are meals and restaurants, simply with the versions
meals: id, restaurant_id, price, etc.
restaurants: id, name, location, etc.
To make the query I use the following code:
$this->db->join('restaurants', 'restaurants.id = meals.restaurant_id');
$query = $this->db->get('meals');
which returns the same result as running this:
$query = $this->db->query('SELECT * FROM meals INNER JOIN restaurants ON restaurants.id = meals.restaurant_id');
The problem is that when I access the result in the form of a php array or and object (as supplied by codeigniter DB class), there is only one id returned, the restaurant id, and I need the meal id. How can I get it to spit out the meal id?

I'm not experienced with your current tools (php/codeigniter/etc.), and I'm assuming the problem comes about because both tables have the same name for the "id" column? (That's not normally a problem... but maybe the tools don't handle it right?) As for the SQL query, one way to differentiate columns with the same name is to use aliases in the select statement. Here is an example:
select
m.id as meal_id,
m.price as meal_price,
r.id as restaurant_id,
r.name as restaurant_name,
r.location as restaurant_location
from meals as m
inner join restaurants as r on r.id = m.restaurant_id

try this
SELECT t1.id as mid,t2.id as rid
FROM table_meals as t1
inner JOIN table_restaurant as t2 ON t2.id = t1.`restaurant_id`

Related

MySQL Query Involving 3 Tables And 2 Databases, Can't Get Correct Columns

I'm using the following query to pull data from 3 tables. 2 are in the same database and 1 in a different database. Basically I have recipes in one table, and I'm using the recipieToCountry table to connect to the countries table so I know what country a recipe belongs to.
$contentQuery = $page->dbf->query("
SELECT *
FROM recipes, recipeToCountry, content.countries
WHERE recipes.id = recipeToCountry.recipeId
AND recipeToCountry.countryId = content.countries.id
AND content.countries.origId = '$country'
");
The problem I'm running into is when I call $content->title it returns the title from countries when I want the title from recipies. My understanding is SELECT * is the issue, so I tried to change the query to this:
SELECT title, description, approved, active, id, recipeId, countryId
FROM recipes, recipeToCountry
WHERE recipes.id = recipeToCountry.recipeId
UNION
SELECT id, origId, null, null, null, null, null
FROM content.countries
WHERE content.countries.origId = 1
AND recipeToCountry.countryId = content.countries.id
Unfortunately this query has an error, and I'm unsure how to fix it. When I removed the last AND the UNION doesn't seem to work as well. Any ideas on what changes I could make to get the correct columns?
Simple JOINs should work well:
select r.*, c.*
from recipes r
join repiceToCountry rc on r.id = rc.recipeId
join content.countries c on c.id = rc.countryId
where c.origId = '$country'
You must make sure you have SELECT privileges on the other database.
Also, you can replace r.*, c.* by the specific columns you want to show.
I developed a habit a long time ago of always putting the table alias/name before every field in the query. This way you can modify the query later on without worrying about fields names that conflict when you add tables to the query. I also prefer joins to multiple FROM tables. (It's easier to see the logic)
I would change your first query to this:
SELECT r.*, c.country /* any other fields in country besides title */
FROM recipes as r
LEFT JOIN recipeToCountry as rtc ON rtc.recipeId = r.id
LEFT JOIN content.countries as c ON c.id = rtc.countryId
WHERE c.origId = '$country'
You can leave the word "as" out to make it look a little cleaner, but I leave it in there to show what's happening a little better.

SQL: 3 Table Inner Join Returns Multiple Results

SELECT video.name, video.description, video_source.url, bitcast_user.username
FROM video
INNER JOIN bitcast_user ON video.account_id = bitcast_user.id
INNER JOIN video_source ON video_source.video_id = {$_GET['id']};
This returns results with incorrect video names, descriptions and associated accounts but correct sources. There is a one-to-many relationship between users and videos, and videos and sources.
You shouldn't do an INNER JOIN on a variable - that belongs in the WHERE clause. (Actually - I was even surprised that this worked at all.) I think you need a query like this:
SELECT video.name, video.description, video_source.url, bitcast_user.username
FROM video
INNER JOIN bitcast_user ON video.account_id = bitcast_user.id
INNER JOIN video_source ON video_source.video_id = video.video_id
WHERE video_source.video_id = {$_GET['id']};
(I'm not sure about video_source.video_id = video.video_id because I don't know how the column is named in the video table.)

Inner Joining with two tables

I need a little help setting up my query. I'm simply trying to access the amount of people who are in the same 'clan' by joining these two tables together, clan, users. Each users has a column 'clan' which is the same as the table clan's column 'roomOwner' and then I'm trying to get the table clan's information along with the amount of members so it would be like: room, roomOwner, members
So basically all I have is this:
SELECT c.*, count(u.clan) AS members FROM clans c inner join users u WHERE c.roomOwner = u.clan ORDER BY members;
It only shows one clan though. Any help please?
Your query has no GROUP BY clause. and I think it's only returning single record right? LEFT JOIN is needed here since there are possibilities that a clan has no member.
SELECT b.roomOwner, COUNT(a.clan) memberCount
FROM clan b
LEFT JOIN users a
ON a.clan = b.roomOwner
GROUP BY b.roomOwner
ORDER BY memberCount
You forgot GROUP BY. Do you have some "id" column in "clans" table? Group by that "id"
SELECT c.*, count(u.clan) AS members
FROM clans c
inner join users u ON c.roomOwner = u.clan
GROUP BY clans.id
And you need LEFT JOIN there instead of INNER JOIN if you want to see info about all clans, even having 0 users.
Perhaps this will help:
select c.*, count(links.id) as members
from clans c
left join users u on c.roomOwner = u,clan
group by u.clan
order by members

PHP /MySQL - *-to-Many Relationships

So, I understand how the relationships work in mysql but I'm having a hard time figuring out how its implemented in my code.
For example, say I have the 3 tables.
Table 1: users - user id, username, user city
Table 2: categories - category id, category name
Table 3: user_categories - user id, category id
If I were to query the database for every user that was in a particular city and list them out with the all of the categories they belong to... How would I do this? Would I need to loop through the results and do a separate query for each user, then list the results? Or, is there some magic query that will return a multidimensional array?
I believe the above would be many-to-many, correct me if I'm wrong....
EDIT In the user_categories table, a user can contain more than 1 category, I'm trying to figure out how to return all of them
Thanks!
You're absolutely right, it is a many-to-many query.
And from what I understand, what you're looking for is the ability to have some kind of hierarchical result to display, meaning for one user, have an array of all the categories he's assigned to...
Couple of things you could do:
Option 1: Query the users table:
SELECT u.user_id, u.username, u.user_city WHERE city = 'somecity';
From the results, get all the user_id's that match, put them in an array.
array(1,3,4,5)
Then execute a query by joining the 2 tables categories and user_categories, and passing the array as a comma separated list in a where in:
SELECT user_categories.user_id, categories.category_name
FROM user_categories INNER JOIN categories ON user_categories.category_id = categories.category_id
WHERE user_categories.user_id IN (1,3,4,5)
This will give you a list of user-id, category name that you can use in your script with the previous results to build your result set
option 2: my preferred, use MySQL's GROUP_CONCAT(http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat).
SELECT users.user_id, users.user_name, GROUP_CONCAT(categories.category_name) AS categories
FROM users
INNER JOIN user_categories ON users.id = users_categories.user_id
INNER JOIN categories ON user_categories.category_id = category.id
WHERE user.user_city = 'somecity'
GROUP BY user.user_id
This will return something like:
user_id username categories
1 u1 cat1, cat2, cat3
2 u2 cat1, cat3
You can specify the separator by using SEPARATOR in group_concat.
You need to JOIN the tables.
If I were to query the database for every user that was in a particular city and list them out with the all of the categories they belong to
SELECT *
FROM users
INNER JOIN user_categories
ON (user_id)
INNER JOIN categories
ON (category_id)
WHERE ...
You could try:
SELECT u.user_id, u.username, u.user_city, c.category_id, c.category_name
FROM users u
INNER JOIN user_categories uc ON u.user_id = uc.user_id
INNER JOIN categories c ON uc.category_id = c.category_id
WHERE u.user_city = 'Cityname';
I haven't tested this, and there might be a more efficient way to do it, but it should work.
If you are unfamiliar with joins in mysql, check this out.

Retrieving MYSQL Join values from PHP

I have two or more tables which hold values under the same column name. Now when I join these two tables the column names stay the same. When retrieving these values in PHP ($row['name']) I encounter problems since the column 'name' is used twice.
Are there any possible means of separating these two columns inside the query?
SELECT *
FROM stories s
JOIN authors a ON a.id = s.authorid
Table stories
id, name, content, date
Table authors
id, name, date
When i join these two i get one table with similar 'name' columns.
Is there anyway to separate the two tables so the author table has a prefix in front of it? E.g. authors_name /authors_*
Yes, change your SQL this way :
SELECT
s.Id as StoryId,
s.Name as StoryName,
a.Id as AuthorId,
a.Name as AthorName,
FROM stories s
JOIN authors a ON a.id = s.authorid
Then in php, use StoryId, StoryName, AuthorId and AthorName instead of Id or Name.
Hope it helps you.
Yes there is!
SELECT *, stories.name AS s_name, authors.name AS a_name
FROM stories s
JOIN authors a ON a.id = s.authorid
And there you have it. All fields plus two extra! ;)
Hope it helps.
Sorry you can't really do prefixing on a field level, but if you can call 2 queries, just use
SELECT s.*
FROM stories s
JOIN authors a ON a.id = s.authorid
The result set will only contain stories fields and you can use the fields as you normally would with php. Then just do the same again for authors.

Categories