I have more than one table in my query
$query = mysql_query("SELECT * FROM reservation r, users u ...")
while( $fetch = mysql_fetch_assoc($query)){
if($fetch['u.id'] == $fetch['r.id'])
...
And here is the problem I have same column name on tables and when i try to compare the id of reservations with the id of user i get only the id of users!!!
I can replace the '*' with the column names and to change their name with AS (SELECT s.id as sid ...) but is there any easier way?
For e.x:
If your two tables both have a column with the same name, then you're only going to be able to access one of those fields in an associative array - the key is the name of the field, so the first one is over-written by the second.
The quick fix is, as you say, to explicitly rename the fields so they don't clash. Though you might be able to work around it by using mysql_fetch_array - that will give you all the fields, but you'll need to access fields by index number; so if you change table structures, you'll need to re-write code.
The better way is not to have two fields with the same name in different tables, if at all possible - if they were called reservationID and userID, you'd avoid this completely. I try not to re-use fieldnames unless it's a foreign key.
Related
I have 2 tables named "rel_eq" and "rel_cat". From the table "rel_cat" I need to compare the id with the column "relcat" in the table "rel_eq". And I need to select all columns from both tables so that I can output in a loop. In some lines in the "rel_eq" table, there is no value in the relcat column. I need to make sure there is either no value where it is missing, or a default, like "uncategory". My code $eq_arr = $wpdb->get_results("SELECT * FROM $table_name CROSS JOIN $table_cat"); but I have to sort through all the id and assign the same id from another table. Please tell me how to do this.
You will need to run the following:
$eq_arr = $wpdb->get_results("SELECT * FROM rel_eq join rel_cat on rel_eq.relcat = rel_cat.id");
If you want a record even when there is no match, use INNER JOIN and handle the problem in your cycle.
I'm about to create a database that has fields that will appear in a few different tables (as keys). For example, in my listing table I will have MLS_ID. This field will also appear in the listing_photos table. Should I prefix the field name to make it unique: listings_MLS_ID as an example?
there is absolutely no point in doing that. you could ALWAYS prefix your fieldname with both database and table names, getting your unique identifier, keeping the name itself neat and concise.
listings.mls.id
will address an id field in the mls table which belongs to listings database.
this is going to be quite flexible: any time you need long unique identifier - you have it.
in all other cases you can use short name.
Name the key the same in both tables (MLS_ID). The database server rewards you for doing this by letting you use the more concise USING clause:
SELECT * FROM listings
JOIN listing_photos
USING (MLS_ID)
Rather than this:
SELECT * FROM listings
JOIN listing_photos
ON listing_photos.listings_MLS_ID = listings.MLS_ID
this is personal preference.
for me:
i do not prefix with the local table name except on the primary key. e.g.
PERSON table will get a PERSON_ID column, ADDRESS table will get ADDRESS_ID etc.
the PERSON_ADDRESS table gets PERSON_ID and ADDRESS_ID, not something else.
in your queries, the column names are equal when they should be equivalent as keys, and the table alias tells you which is which.
I am currently working on a school system where we have a parent course and a child course (meta_courses in Moodle).
So, we have a table mdl_course_meta and it has 3 fields. Id, parent_course and child_course.
My problem is that a parent course can have many child courses so that means, for example, a parent_course = 50 can appear two times in the table which means it has 2 child courses. I just want to be able to find all the parent courses without it returning the same value twice or more times. I'm currently using this query right now which obviously doesn't do what I want:
$q = "SELECT * FROM mdl_course_meta";
I am working with PHP as well by the way.
Thanks a lot.
SELECT DISTINCT parent_course from mdl_course_meta
That should do it if you just want the course names. One thing to keep in mind, if you want other fields this is not going to work the way you want it to(how would it know which record to choose if there are multiple records with the same parent_course and you only want one).
This approach can only be used if you only want to return the parent_courses without duplicates.
DISTINCT helps to eliminate duplicates. If a query returns a result that contains duplicate rows, you can remove duplicates to produce a result set in which every row is unique. To do this, include the keyword DISTINCT after SELECT and before the output column list.
$q = "SELECT DISTINCT parent_course FROM mdl_course_meta";
If you don't want duplicate values in a single column, use GROUP BY parent_course.
In this way you are free to select any column.
If you only want distinct values for a particular column column, then you can use GROUP BY:
SELECT *
FROM mdl_course_meta
GROUP BY parent_course
The values in the other columns will be arbitrary. This will work in MySQL 5.x.
MySQL 4.x won't let you be arbitrary, so you can't mix aggregate and non-aggregate columns. Instead, you'd have to do something like this, which gets a bit complicated:
SELECT MAX(col1), MAX(col2), parent_course, MAX(col4), ...
FROM mdl_course_meta
GROUP BY parent_course
This way, the values aren't arbitrary. You've specified the ones you want.
I had my query set up the other day as so
$query = "SELECT card_id,title,description,meta_description,seo_keywords,price
FROM cards,card_cheapest order by card_id";
As you can see, I was selecting card_id,title,description,meta_description,seo_keywords from the table cards, and price was coming from cheapest_card. They both have the card_id in common (in both tables). However, I ran into a bit of an issue. When I run the query in navicat lite, I receive an error "card_id is ambiguous". Was I doing something wrong?
When 2 or more tables have a column that is named the same, you have to qualify the table you want the column to be from.
i.e.:
$query = "SELECT cards.card_id,title,description,meta_description,seo_keywords,price
FROM cards,card_cheapest order by card_id";
Furthermore, do you really want to run the query this way, without a WHERE/JOIN-clause to define how to JOIN the two tables?
$query = "SELECT cards.card_id,title,description,meta_description,seo_keywords,price
FROM cards,card_cheapest WHERE cards.card_id = card_cheapest.card_id
ORDER BY card_id";
When you have the same column name in two tables you're selecting from, you have to prefix the part in the SELECT with one of the table names (it doesn't matter which if it's the same data)
such as SELECT cards.card_id, ...
EDIT: However, cularis's answer is much more explanatory than mine, and take note about joining the two card_id columns if you want to get correct results.
When you run queries that get information from multiple tables with shared field names you need to specify from which table you want to extract what field. You do this by specifying the table name before the field name.
In your case you have two options:
cards.card_id or card_cheapest.card_id.
Also I agree with #cularis, you are probably better of doing a join, but still you will need to specify which card_id you want to select: the one from cards or card_cheapest.
I decided to use favs (id's of users which marked that post as a favorite) as a comma separated list in a favs column which is also in messages table with sender,url,content etc..
But when I try to count those rows with a query like:
select count(id)
from messages
where favs like '%userid%'
of course it returns a wrong result because all id's may be a part of another's
For example while querying for id=1 it also increase the counter for any other content that is favorited by user id 11...
Can you please tell me your idea or any solution to make this system work?
With a few or's, you can have an ugly solution:
select count(id) from messages where favs like 'userid,%' or favs like '%,userid,%' or favs like '%,userid'
There's likely a more elegant solution, but that one will at least return the result you're looking for, I believe.
Is it possible to change your data model such that the association between users and their favorite messages is instead stored in another table?
Storing the associations in a single column negates the advantages of a relational database. You pay a performance cost using the like function, you can no longer store additional data about the relationship, and the data is harder to query.
An alternative model might looking something like this (can't include an image since I'm a new user, but I made one here):
users
- id
messages
- id
favorite_messages
- user_id (foreign key to users.id)
- message_id (foreign key to messages.id)
With that in place, your original query would be simplified to the following:
select count(1) from favorite_messages where user_id = userid
Additionally, you can do things like get a list of a user's favorite messages:
select
*
from
messages
inner join favorite_messages
on messages.id = favorite_messages.message_id
where
user_id = userid
should using this :
SELECT count(id) FROM messages WHERE FIND_IN_SET('userid',favs) > 0
You might have to get the value, explode it with PHP and then count the array.
There are ways to do it in MySQL, but from what I've seen, they are a hassle.