How to solve this perticular query in MySql? - php

Problem Statement To Solve:
You need to store employee information (name, age, gender and address) and Project information (name, client name, client city) in database. Employees can work on multiple projects and a project can have multiple employees. Some employee might not be on any project.
Please create table structure for this and necessary constraints, don’t use create table query just structure is important and show primary key and data type of each column.
For above scenario write a query for following case:-
To get list of projects, For each project the details needed in the list are-project name, client name, no. of employee working on project.
I little bit understand that there is problem in table 1 that is Project table because it's not normalized

Can’t make much suggestions about constraints or keys, but
definitely Employee and Projects tables need to be primary keys as Employee ID and Project ID respectively,
the gender in employees table could be enum.
Project_employees table is suggested to have a primary key as well, so it can uniquely identify a record in case there are multiple entries of same project or employee ids. That way there won’t be a need of using both of these columns in criteria.

employee
id|name| age| gender| address
client
id|name|city
project
id| name| client_id(FK client.id)
project_employee_mapping
employee_id (FK employee.id) | project_id (FK project.id)
Query:
SELECT p.name, c.client_name, COUNT(pem.employee_id)
FROM project p, project_employee_mapping pem, client c
WHERE pem.project_id = p.id
AND c.id = p.client_id
GROUP BY p.id

Related

multiple tables select

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.)

How to build table from two tables, one with useless unique identifier (WordPress wp_usermeta table)

Use case background: I'm using a WordPress site to manage memberships, and the ID Card software on my PC will connect to a table to generate its information. It can connect to only one table.
Goal: I need a table called "id_card" that contains the columns (member_number, first_name, last_name, exp_date), and it's populated with users that have been modified within the last month ("membership" table has a column titled "moddate" that I can use as the criteria).
Challenge 1: I need to pull exp_date from table "membership" and the other values -- member_number, first_name, last_name -- all come from a table called "wp_usermeta" (a default table for WordPress). Both source tables contain user_id to associate the information to the same user account. I believe this requires some kind of LEFT JOIN, but I haven't been able to get it to work.
Challenge 2: the bigger challenge: wp_usermeta table contains all the different user attributes in ROWS instead of COLUMNS. So the columns are titled "user_id, meta_key, meta_value" and there might be 30 rows for a single user. If I want to SELECT user 49's first name, it looks something like this:
SELECT meta_value FROM wp_usermeta WHERE user_id=49 AND meta_key='first_name'
Question: How do I write this query so it will INSERT INTO the table "id_card" the values from the two tables, using the user_id to keep it all lined up, especially when I can't use solely the user_id as a unique identifier (i.e. the only way I know to narrow it down to someone's first name is use both their user_id and the meta_key) in the wp_usermeta table?
There is a major problem with your wanting to copy data. If the user changes their data then your copy will be out of date. If you look at the wp_users table there is a ID field. This points to the relevant entries in the wp_usermeta table (user_id)
SELECT `wp_users`.*
, `wp_usermeta`.*
FROM `wp_users`
INNER JOIN `wp_usermeta` ON (`wp_users`.`ID` = `wp_usermeta`.`user_id`)
WHERE ID=1;
Now this will return multiple rows. If you want a single record then you'll need to do
SELECT`wp_users`.*
, (SELECT meta_key FROM wp_usermeta WHERE meta_key='wp_user_level' AND user_id=1) AS user_level
, (SELECT meta_key FROM wp_usermeta WHERE meta_key='show_syntax_highlighting' AND user_id=1) AS syntax_highlighting
FROM `wp_users`
WHERE ID=1;
Just repeat the subquery statements for as much info that you want to return. The subquery can only return a single value.

Find the same value in three Colomns with same name but in different tables

I am currently making an android app which uses a feed to display statuses made by users. I have three tables within the same database, each has username either as a primary or unique key column, but each table has different information relating to that user.
For instance, the first table ===>> tbl_users:
username
fname (first name)
mname (middle name)
lname (last name)
etc. (the list is long)
The second table ===>> tbl_userprofilepictures:
profilepictureID
username
profilepicturepath
The third table ===>> tbl_user_feed:
postID (the status' unique ID)
username
status
imagepostpath (the path to the image uploaded with the status)
timestamp
I want to be able to search for the username across all three tables and display the relevant information relating to them on their post. For example I will need their name and surname for tbl_users and I will need their profilepicturepath for tbl_userprofilepictures as well as their status, imagepostpath and timestamp from tbl_user_feed.
Would I need to do this in a seperate PHP file or in the app itself? PS I'm fairly noob at PHP so please feel free to help a bro out.
May the force be with you.
You can use JOIN.
What is JOIN ?
An SQL JOIN clause is used to combine rows from two or more tables, based on a common field between them.
Source : w3schools.com Joins
Here is the sample I made base on your tables given. For these one our common field is username.
SELECT CONCAT('a.fname', 'a.lname'), b.profilepictureID, c.status, c.imagepostpath, c.timestamp
FROM
tbl_users as a
LEFT JOIN tbl_userprofilepictures as b ON b.username = a.username
LEFT JOIN tbl_user_feed as c ON c.username = a.username
Using Alias (table_name as custom_name) is a good practice in joining the tables

Get rows from a MySQL database where the number of foreign keys are variable.

A subset of my database contains 3 tables
users
user_details
tasks
The main column of the user table is:
id {PK}
The user details table contains information about the users (only some users have these details, students). Thus the main columns of the users details table are:
user_id{PK,FK} | supervisor_id {FK}
The supervisor_id is an id in the users table. Each student has one supervisor.
Lastly, there is the tasks table where only students create tasks and the main columns of the tasks table are:
task_id{PK} | user_id{FK}
The problem I am having is getting a proper query for, if a supervisor wants to see all his students tasks. I know you can query all the students in the user_details table who have the supervisor's id. Then create another query where you select all the tasks whose user_id matches that of the first query performed.
This does not seem like a very efficient was to go about achieving this result. Are there better alternatives?
select ud.supervisor_id, ud.user_id, t.task_id
from user_details ud, users u
where ud.user_id = t.user_id
What you are looking for is a join. Instead of writing two separate queries to get the information, a join will allow you to connect the tables that you have in one query and get the information you need much faster.
Select *
From user_details ud
join tasks t
on ud.user_id = t.user_id
Where ud.supervisor_id = ?
The join essentially allows you to create one big table out of all of the columns of the tables you are using. The on keyword tells sql which values go together, so that you know all of the tasks belong to the student whose id matches the id that the supervisor has. Then, you can select whatever columns you like out of either table (as well as a lot of other fancy things).

MySQL - Database design - separate tables for users and profile

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.

Categories