Have SQL Table Fields Automatically Link to Lookup Tables - php

I have a few tables in a MySQL database similar to this setup:
major table
---------------------
| id | name |
|-------------------|
| 0 | Architecture |
| 1 | Biology |
| 2 | Chemistry |
---------------------
college table
----------------------
| id | name |
|--------------------|
| 0 | Georgia Tech |
| 1 | Virginia Tech |
| 2 | Cal Tech |
----------------------
users table
----------------------------------------------
| id | name | major_id | college_id |
|--------------------------------------------|
| 0 | John Smith | 2 | 0 |
| 1 | Kevin Lee | 2 | 1 |
| 2 | Matt Anderson | 0 | 2 |
----------------------------------------------
Using PHP, I want to get all the information for a user using a query similar to this:
SELECT * FROM users WHERE name=`$user`
Is there someway for MySQL to automatically link the "major_id" and "college_id" columns to the "major" and "college" tables in a way where the query above would return the appropriate values?
If it is not possible with a single query, would multiple queries slow down performance considerably?

SELECT * FROM users WHERE name='$user'
This query (yours has back ticks around $user, back ticks are for column names, use double/single quotes) will only return values from the users table. You can't make MySQL "automagically" construct your joins. You have to do it explicitly, otherwise, how would you get information only from the users table if you wanted to? Use a JOIN like this:
SELECT users.name AS Username, college.name AS College, major.name AS Major
FROM users
INNER JOIN college ON users.college_id = college.id
INNER JOIN major ON users.major_id = major.id
Limit the retrieved columns by only selecting the ones you really need. So instead of the asterisk, write users.name etc.
The JOIN syntax is described in the MySQL Docs.

Joins are what your looking for, in this case your SQL would be:
SELECT `users`.`name`, `major`.`name`, `college`.`name`
FROM `users` WHERE `users`.`name`='name'
INNER JOIN `major` ON `major`.`id`=`users`.`major_id`
INNER JOIN `college` ON `college`.`id`=`users`.`college_id`
You can also alias your field names so you get something a bit more usable out:
SELECT `users`.`name` AS `applicant_name`, `major`.`name` AS `major_name`, `college`.`name` AS `college_name`
FROM `users` WHERE `users`.`name`='name'
INNER JOIN `major` ON `major`.`id`=`users`.`major_id`
INNER JOIN `college` ON `college`.`id`=`users`.`college_id`
More on Joins at http://dev.mysql.com/doc/refman/5.0/en/join.html

Related

PHP how to use where in to replace left join in mysql?

I have 2 table, records and common_member.
records just store a plugin data. (Not frequently queried) but common_member was a huge data table and frequently queried.
Sample data of common_member
+--------+-----------+
| uid | username |
+--------+-----------+
| 1 | admin |
| 2 | test1 |
+--------------------+
Sample data of records
+--------+-----------+-----------+
| uid | amount |createtime |
+--------+-----------+-----------+
| 1 | 50 |1234567 |
| 1 | 100 |5555555 |
| 2 | 2000 |9999999 |
+--------------------------------+
Normally I am using $lrecord = mysqli_fetch_all("SELECT t1.*,t2.username FROM records t1 LEFT JOIN common_member t2 ON (t1.uid = t2.uid) ORDER BY t1.createtime").
But after that I was be informed if using leftjoin connect with common_member, It will be very inefficient and there was a way just using where in the get the username from common_member.
So, how to get the username from common_member without using leftjoin?
I want the final result of records array to be: (Means username from common_member join to records)
+------+-------------+-----------+-----------+
| uid | username | amount | createtime|
+------+-------------+-----------+-----------+
| 1 | admin | 50 | 1234567 |
| 1 | admin | 100 | 5555555 |
| 2 | test1 | 2000 | 9999999 |
+--------------------------------------------+
My question is, how to use where in get the username in common_member without leftjoin ?
Thank you.
But after that I was be informed...
(with respect...) who informed you ? phpMyAdmin ? another interface ? your friend ? a blog.. ?
there is no problem with the left join, but you must check the indexes of your tables.
It is necessary that in both tables, there is an index (preferably primary) on the field uid.
Otherwise, the request will not be optimized and can be slow.
The answer to your question, how to use where in get the username in common_member without leftjoin ?, is that you can't.
The where clause is used for filtering results, not to add information to them. This could be usefull if you just want to retrive all rows in records which have an existing user. However, if database was properly designed, such a question wouldn't be asked, because records.uid would be an non-nullable foreign key referencing common_member.uid.
Hence, it wouldn't be necessary to make a left join, but only a join.
But, supposing this isn't your case, and the database isn't properly designed, and records.uid isn't a foreign key, then
select *
from records
where uid in (
select uid
from common_member
)
would return all records of existing users. But still, no username.
The only solution is to execute a join, as you are already doing:
SELECT t1.*,t2.username
FROM records t1
JOIN common_member t2 ON (t1.uid = t2.uid)
ORDER BY t1.createtime

Multiple SQL fetch and print html-code if two tables is true

I'm trying to achieve a PHP, SQL and HTML solution. This is probably commonly done.
I have coded a project overview system from scratch. The state right now is that I have a SQL table for USERS and another table for PROJECTS. It works great to sign in with each user and also to list all projects for all the users.
But to be able to track which users that are connected to each project I created a third SQL table which is called PROJECTMEMBERS. It contains the rows USERS_ID and PROJECTS_ID which are supposed to hold the ID from the user and the project to be able to track the projectmembers. I'm not sure if this is the best solution but found it in another thread and thought it made sense. But now..
I have issues to figure out how to access different SQL tables in the same mysqli_fetch() query. How is this possibly done to present the USER IMAGE in each project? The current fetch is used to present all the projects but I still want to show all projects, but with an image of the active users on the project on each.
I hope I was clear enough for anyone to understand. Looking forward to any help out there.
SQL STRUCTURE EXAMPLE:
tbl_USERS tbl_PROJECTS
| id | username | USER_IMG | etc | | id | PROJECTNAME | DATE | etc |
---------------------------------- ----------------------------------
| 1 | XXXX | XXXXXXXX | 1 | | 1 | AAAA | AAAA | 1 |
| 2 | YYYY | YYYYYYYY | 2 | | 2 | BBBB | BBBB | 3 |
| 3 | ZZZZ | ZZZZZZZZ | 1 | | 3 | CCCC | CCCC | 4 |
tbl_PROJECTMEMBERS
| USERS_ID | PROJECTS_ID |
-------------------------
| 1 | 1 |
| 1 | 5 |
| 2 | 1 |
How it should be presented where USER_IMG is fetched from the users table:
-------------------------------- --------------------------------
| PROJECTNAME | | PROJECTNAME |
| DATE | | DATE |
| | | |
| | | |
| USER_IMG, USER_IMG | | USER_IMG, USER_IMG |
-------------------------------- --------------------------------
--------------------------------
| PROJECTNAME |
| DATE |
| |
| |
| USER_IMG |
--------------------------------
As you have 3 table users and projects and user_projects and you are fetching only projects from projects table then you can add join the first query where you fetch the projects it could some like this
SELECT p.,user. FROM projects as p
INNER JOIN user_projects as up
ON up.project_id = p.id
INNER JOIN users
ON users.id = up.user_id
Above I have used multijoin where project table connected with user_project and user_project conned with users table and in the select query we have fetch project and users table.
In above query you might get query if same attribute get repate into the both table like (ambiguity) so you can just skip the error just by alise it
SELECT user.id AS 'User ID', project.id as 'Project ID', project.name as 'Project Name' from user tbl_USERS , project tbl_PROJECTS, userprojects tbl_PROJECTMEMBERS where user.id = userprojects.USERS_ID AND project.id = userprojects.PROJECT_ID
This would be your mysql query, it would fetch the user id as User ID, project Id as Project ID, and project name as Project Name.
You can access those variables in plain php and output anyway you like.
Something like this?
$query = "SELECT a.*, b.* FROM USERS a INNER JOIN PROJECTS b on a.userID = b.userID
RIGHT JOIN USER_PROJECTS c ON a.userID = c.userID
WHERE a.userID = $variable";
$result = $db->Execute($query)
foreach($result as $data){
if($data['userID'] == $data['projectID']){
//do stuff here
}
}

How should i store entities with only a few possible values?

How should i store data like users's gender, religion, political views which is selecting from a list of 2-8 max values like 'male', 'female' or 'orthodox', 'muslim','judaism','catholic' etc? Also this values is constant, even admin cannot change 'female' to something else. In a Database it looks wierd to store a similar tables with only this 2-8 values and make JOIN with a parent table on foreign key. Second way - special object inside program code - but it's always bad to mix program logic with a data.
Whether or not something is looking "weird" depends on personal preferences or design structures. However, it is entirely logical to store anything in a database that has to do with, well, data. Even a given set of options can change in the distant or not so distant future. I can't count the times a client asked me to change a set of options a day, a week, or even a few years after having ensured me that the set wouldn't change, ever.
Storing a list of options in a separate table is part of a relational database design. Relational database designs make it easy to get a set of data which includes or even excludes the options in any way in my opinion.
I'd recommend doing it the good, old fashioned way, for example:
Table user (id, user_name)
Table option (id, option_label)
Table user_option (id, user_id, option_id)
A user that is both male and catholic would have a relation with two options:
Table user Table option Table user_option
+----+-----------+ +----+--------------+ +----+---------+-----------+
| id | user_name | | id | option_label | | id | user_id | option_id |
+----+-----------+ +----+--------------+ +----+---------+-----------+
| 1 | john | | 1 | male | | 1 | 1 | 1 |
| 2 | melody | | 2 | female | | 2 | 1 | 6 |
| 3 | gerald | | 3 | orthodox | +----+---------+-----------+
+----+-----------+ | 4 | muslim |
| 5 | judaism |
| 6 | catholic |
+----+--------------+
Showing all selected options per user can be done with the following query:
SELECT `u`.*, GROUP_CONCAT( `o`.`option_label` SEPARATOR ', ' ) AS `options`
FROM `user` AS `u`
LEFT JOIN `user_option` AS `uo` ON `uo`.`user_id` = `u`.`id`
LEFT JOIN `option` AS `o` ON `uo`.`option_id` = `o`.`id`
It must go in a table, even if it make you makes joins. The join will be done over a PK, so there is little overhead

count number of rows that have the same combination of two colums

Hi I have 2 table Offense table and User_jobs table
offense table:
crime_id |crime_type |casenumber|
---------+-----------+----------+
1 | 3 |1 |
2 | 3 |1 |
1 | 3 |2 |
12 | AA |2 |
user_jobs table:
casenumber |disposal_status |
-----------+----------------+
1 | yes |
1 | yes |
2 | no |
2 | no |
what i want is to count the number of rows with the same combination say crime_id=1 and crime_type= 3 but these must have a disposal status of yes in the user_jobs table.
i want to do this in mysql. pliz help
sorry but i am new to mysql. i now want to display the real names of those id not the id themselves.
the tables with these IDs are crime_category and Crime_type Crime_catgory
table:
category |crime_id |
-----------+----------------+
theft | 1 |
murder | 2 |
rape | 3 | 2 |
no |
Crime_type table:
Crime_type |id |
---------------+----------------+
administrative | yes |
criminal | yes |
You can do this with a simple inner join and an aggregate function:
select
o.crime_id,
o.crime_type,
count(*)
from
offence o
join user_jobs uj
on o.casenumber=uj.casenumber
where
uj.disposal_status='Yes'
group by
o.crime_id,
o.crime_type
This will pick up distinct combinations of the first two columns joined as they should tot he jobs table and only where the disposal_status is equal to 'Yes'
Edit: You would probably do really well to have a read of this Q&A that I put together for exactly this sort of situation - where I give you the code for it, but would like to explain this is a lot more detail. The Q&A explains why this type of thing (and many many others) work and how they do so:
How can an SQL query return data from multiple tables
Edit 2:
select
o.crime_id,
o.crime_type,
ct.category,
count(*)
from
offence o
join user_jobs uj
on o.casenumber=uj.casenumber
join crime_type ct
on o.crime_type=ct.crime_id
where
uj.disposal_status='Yes'
group by
o.crime_id,
o.crime_type,
ct.category,

query to imlement block list

I have two tables a and b as follows to implement a simple block list where users can block other users.....
Table A
+------------+--------------+------+
| Name | phone |userid|
+------------+--------------+------+
| Mr Sasi | 01225 708225 | 1 |
| Miss Brown | 01225 899360 | 2 |
| Mr Black | 01380 724040 | 3 |
+------------+--------------+------+
Table B
+------------+--------------+
| blockedbyid| blockedid |
+------------+--------------+
| 1 | 2 |
| 2 | 3 |
| 1 | 3 |
+------------+--------------+
"blockedbyid" is id of user who has blocked the user in "blockedid".
I need to join the two tables and fetch all records from table A such that the result has all users who are not blocked by a particular user [ie blockedbyid='XXX'].. Can you guys give the SQL query so that i can fetch the records as a recordset??? I dont want to fetch two different rowsets and compare it in php....
Something like this should work
Parameter :USERID
SELECT * FROM TABLEA WHERE userid NOT IN (SELECT blockedid FROM TABLEB WHERE blockedbyid = :USERID)
Using join
SELECT u.* FROM TABLEB b, TABLEA u WHERE b.blockedbyid = 'XXX' AND b.blockedid = NULL
It may work like that, give it a try.
Roadie57 solutions seems better though.

Categories