I don't know if it's possible but this is what I want to do.
I have three tables
Accounts
id | username | pass
Cars
id | plate | id_ac | kilometers // in the id_ac I add manual the id of the car's owner.
Trips
id | plate | places | date | active
Now I want when the user is logged in to see tha Trips that are active with his car.
So I want to
SELECT from Trips the plate, places, date WHERE active=0 AND id= ? (the logged user's id)
But the table trips doesn't have the id of the owner of the car. So I want somehow to select the values of the table Trips of the car that logged user owns.
Any idea how can I do that?
You should have a look at table joins. This looks like it is what you are looking for:
SELECT t.plate, t.places, t.date FROM Trips as t JOIN Cars as c ON t.plate = c.plate WHERE t.active = 0 AND c.id_ac = ?
Have a look at this. This is a pretty nice way of explaining the table joins.
http://www.sql-join.com/sql-join-types
I am not getting into DB architecture and deeper stuff, but it can help you with your task at hand
What you are referring to is primary and forgein key.
Your primary key is a unique key, which can identify every record in your table. In your user table that is the id. It has to be unique.
When you are now creating trips in your trips table, you will have to "link" your record to the specific user. Here you are referring to the primary key in user's table. So you have a new column user_id inside your trips table, where you will store the user id, who is connected to that trip.
When using the user id in other tables, you are having a "foreign key".
For each trip you will have to create a foreign key for the car and for the user. This can be the number plate and the user id.
If you want to see all the tracks for a specific user, you can make a JOIN with the user id in tracks. If you want to see all tracks for one car, you will just JOIN with the plate.
(I can just suggest reading some information about primary/ foreign key. It is fundamental when designing a database structure as you did above.)
Related
I have a users table with this structure:
user_id | name | email | mobile
And another table called products with this structure:
product_id | name | price
now I want to add wish list to my project, so that a user can add some products into his wish list (with his favorite categories. Exmaple: add a wish list category called my favorite clothes and add product_id = 55 to that category)!
Now I have 2 options:
1. Add another colum to users table called user_wish_list and then store serialized data in that column like below:
$user_wish_list = [
'user_category_1' => ['product_id_1', 'product_id_2', ....] ;
];
and store serialize($user_wish_list) in user_wish_list column.
2. create 2 tables as below:
tabe: wish_list_categories
user_id | category_id (PK) | category_title
and
tabe: wish_list_items
category_id (FK) | item_id | product_id (FK)
and finally create a relation between these tables (By SQL join)
which option is better? I personally think the second one!
one of the reasons for my choice is that I can access to data with pure SQL query
like below (I do not have to process data after fetching from database by using unserialize() ):
SELECT users.user_id, users.name, wish_list_categories.category_id,
FROM Orders
INNER JOIN Customers ON users.user_id = wish_list_categories.category_id
But what about other advantages?
Or let me ask a more general question: when we exactly use relational tables instead of use column? (consider one-to-one relationship)
Use tables. In general, don't store structured data in individual SQL values. Let the tables and foreign keys produce the structure you need.
your tables should be like:
1- users table:
user_id|user_name|Email|price
2- products table:
product_id|product_name|category_id|price
3- products_category
category_id|category_name
4- user_wish_list table:
user_id|product_id
I am creating a fantasy football android app where getting the JSON data is done with php files and SQL. My problem involves 2 tables:
player_details
player_id (primary key)
first_name
last_name
user_team
(All id fields except PK are foreign keys linked to the player_id)
user_team_id (primary key)
goalkeeper_id
rightback_id
leftback_id
etc.
I want to be able to run a PHP script, with a simple select statement in it, that will display a user team's details. I also want to include the first and last name of the players, which are linked to the foreign keys in the user_team position id fields. However all I can do is display the user_teams details and the players_id only.
SELECT *
FROM user_team
WHERE user_id = '".$uid."'
In this case, you have to do as many JOINs as the number of positions you have for your teams.
Like,
SELECT u.user_team_name, p1.goalkeeper_name, p2.rightback_name, p3.leftback_name, ...
FROM user_team u
LEFT JOIN player_details p1 ON u.goalkeeper_id = p1.player_id
LEFT JOIN player_details p2 ON u.rightback_id = p2.player_id
LEFT JOIN player_details p3 ON u.leftback_id = p3.player_id
...
WHERE u.user_team_id = <some id>
Doable, but not really good.
Then, you may change your model, and introduce the third table, that ties the player with both team and position, like:
CREATE TABLE team_positions (
player_id INT,
team_id INT,
position TEXT,
FOREIGN KEY player_id
REFERENCES player_details(player_id)
FOREIGN KEY team_id
REFERENCES user_team(user_team_id)
);
To increase the consitancy of data, it could be further normalized by introducing the positions table, than you going to refer it in team_positions by id too.
In the meantime, user_team table would retain just the team details, like name & any other stuff you wanna put there (emblem, perhaps?), along with team id.
This way, you're going to have quite flexible structure. And that is pretty much usual the way of doing stuff in relational DB model.
Hey I have the following MYSQL DB structure for 3 tables with many to many relation. Many users can have many cars and cars can be for many users as showing below:
Users
ID | Name
---------
100|John
101|Smith
Cars
ID | Name
---------
50|BMW
60|Audi
Users_cars
ID | UID | CID
---------
1| 100 |50
2| 100 |60
3| 101 |60
I have a page users_cars.php this page have two drop down lists
list of all users
list of all cars
In this page you can select a user from user's list and select a car from car's list then click add to insert into users_cars table.
What am trying to do is to exclude from user's drop down list all the users that have been linked with all the available cars from cars table.
In the example above user's drop down list will just have "Smith" because "John" linked with all cars available (BMW,AUDI), if "Smith" also has the BMW he will be excluded from the list. I need a select query for this condition and i don't want to use any nest select query to count user records inside users_cars table
If I understand what you are after you need to use GROUP BY in your query. So to select all users:
SELECT ID, UID FROM Users_cars GROUP BY UID
and for all cars:
SELECT ID, CID FROM Users_cars GROUP BY CID
That will group results that are the same, so you only get one instance of each user, or one instance of each car.
I hope I understood your question right.
I think you can so this using some programming -
With PHP/mysql -
Get count of all distinct car ID's
Get count of cars for each user. (making sure this lists only unique car ID's)
Loop through all users and in each loop compare the above two and exclude the user where this condition matches.
SELECT *
FROM users
WEHRE id NOT IN (SELECT uid
FROM (SELECT uid, COUNT(cid), COUNT(*)
FORM cars
LEFT OUTER JOIN users_cars ON cars.id = users_cars.cid
GROUP BY uid
HAVING COUNT(cid) = COUNT(*)
Basically, what you want to do is that (if I understood your problem) :
SELECT UID FROM Users_cars WHERE CID NOT IN (SELECT ID FROM Cars);
But carefull, this is a greedy request (depends on the size of the tables of course) and you should better put a flag on the user table and update then when your user uses the last available car (or with a batch) so you don't run the request too often !
From what I've been reading online, I understood that it's better to split the data into more tables, if possible because of the access times.
Right now I have a table in which I am storing usernames, passwords and join date
This is how my table looks:
'user'
'user_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
user_username VARCHAR(80) NOT NULL,
user_password VARCHAR(255) NOT NULL,
user_join_date INTEGER UNSIGNED NOT NULL,
PRIMARY KEY (user_id) ');
I am trying to create a new table called profiles in which I want to store first name, last name, email, age and gender. What I think is that I need a one-to-one relationship, so I should be using the user_id but I'm not really sure how to implement it.
Should I create another table called profiles with
profiles
profiles_id
first_name
last_name
email
age
gender
and another one which should be the relationship ? e.g.
user_profiles
----------
user_id
profiles_id
Is this right? How would the SQL look for the user_profiles?
Thanks
Don't split the tables. Just add the new columns to your existing user table. You might find later on that splitting tables is a good idea based on actual queries and usage patterns but until you have that kind of data, keep things simple.
If you must create a profile table, don't create a user_profiles table. That would allow an m-to-n relationship which is probably not what you want. A simple user_id column in profiles is better. In fact, it could be both a foreign key and the primary key to make sure that each user row only have one and only one profile row (although by splitting the tables you might still have a user with no profile).
Usually, you create an association table, like user_profiles you have described when one user could have more than one profile, and/or one profile could belong to one or more user.
As you have said, here you have a one-to-one relationship between user and profile. So, you can simply add a user_id column to your profile table, and define it as a foreign key to user table.
Then, a simple JOIN will allow you to query both tables at the same time:
SELECT u.*, p.*
FROM user u
JOIN profile p ON u.user_id = p.user_id
Add a new field in the User table, ProfileId, and set it as Foreign Key (FK). Each time you create a User, you have to assign to it a profile (which will be the ProfileId PK from profile table).
If you want to see also the profile information of a user, you have to do a join
Select username, first_name,second_name
From user u, profile p
Where u.profileId = p.profileId
this
user_profiles
----------
user_id
profiles_id
is used in a many-to-many relationship. By example, you want to assign to an admin some privileges, but those privileges can be also assigned to more admins. Then, you have to create a 3rd table to solve this problem. Here is an example, but you don't need to do this.
You could add a user_id field to your profiles table and JOIN the tables on user_id.
SELECT user.user_username, ..., profiles.first_name, ...
FROM user
INNER JOIN profiles
ON user.user_id = profiles.user_id
This should fetch data combining information from those rows where the JOIN condition is met (i.e. user.user_id = profiles.user_id).
It is true that having more than one tables is a good idea. I am not sure what you mean about access time, but there are other advantages.
- Your users database containing passwords etc is "sacred", you never change its structure and you limit the rights to it (read, write) to the strict minimum.
- You can then have several "satelites" tables such as profiles, private messages, etc which are more flexible, less sensitive and which you can change all the time.
About your question per se, there is no need for a separate table with the relationships. In fact is a very bad idea which will complicate your queries and doesn't have any advantage. Instead, in your profiles database you will have one column that refers back to the user id.
users
--------
id
user_name
email
password
users_profiles
---------
id
user_id
favourite_animal
Table user
user_id |user_username |user_password |user_join_date |profile_id
Table profile
profile_id |first name |last name |email |age |gender
When selecting a user by user id:
SELECT u.*, p.* FROM user AS u INNER JOIN `profile` AS p ON u.profile_id = p.profile_id WHERE u.user_id = 1
But a user should only one gender, one age, one name and surname. Maybe e-mail adresses might be many. I suggest you there is no need to join tables which have a 1-to-1 relation. Instead merge those tables.
I need to know how to link two tables in a php/mysql set up then rank the results?
Here is my situation.
I have a stories table:
storyid
writerid
title
story
submitdate
and a votes table
voteid
userid
storyid
vote
I store a vote up as a 1 and a vote down as a -1
I am looking for a way to join these two table then rank/sort the stories by the number of votes they recieve.
I am open to any ideas about how to do so or a different possible database schema.
I prefer to keep the names of my tables singular. It's not a "Stories" table; it's a "Story" table with multiple rows.
A vote can only be attributed to a single story, so it's a one-to-many relationship between the two. I'd put the foreign key in the votes table and let it point out the story it's associated with. Change your schema if you agree: remove the voteid from the story table and make storyid in vote a foreign key to the story table.
But with that said, perhaps you can try a query like this:
select stories.storyid, sum(vote=-1) as down, sum(vote=1) as up
from stories
inner join votes on (stories.storyid = votes.storyid)
group by stories.storyid
Corrected per ypercube's comment below.