Get row values from foreign key MySQL - mysql

This may sound simple and dumb but how can I get the values of a foreign key from a table and displaying it?
I have a table named "subjects" which contains different school subjects and one column of it is a foreign key referencing from table named "faculty".
TABLE subjects
___________________________________
| sub_id | sub_faculty | sub_desc |
| 1 | 2 | PHYSICS |
| 2 | 3 | MATH |
| 3 | 4 | HISTORY |
|________|_____________|__________|
TABLE faculty
________________________
| fac_id | fac_name |
| 2 | John |
| 3 | Mark |
| 4 | Johnny |
|________|_____________|
I firstly wanted to check if data exist in the "subject" table and then proceed on displaying the row values of the foreign key.
I have this not so working query as displays both JOHN and JOHNNY. I was using LIKE as it will be for the search feature of the system so hopefully you can help me out on this.
SELECT *
FROM subject, faculty
WHERE subject.sub_desc = 'PHYSICS'
AND subject.sub_year = '4'
AND faculty.fac_name LIKE '%JOHN%'
GROUP BY faculty.fac_id

SELECT *
FROM subject s
join faculty f
on s.sub_faculty = f.fac_id
WHERE s.sub_desc = 'PHYSICS'
AND s.sub_year = '4'
AND f.fac_name LIKE '%JOHN%'

Related

How can I insert data to table B with more columns than table A with the same ID (ID matches from both tables)?

So here is my problem, how can i do this :
user with ID = 7 from table A with 3 columns want to insert data to table B with 4 columns but with the same id.
Table A :
| Id | name | password |
| 7 | john | password |
| 9 | mark | password |
| 12 | yuta | password |
Table B :
| Id | user_id | food | drink |
| 1 | 7 | oats | milk |
| 2 | 9 | fish | water |
| 3 | 12 | pear | fanta |
How can i achieve table b in 1 query? both id in both table are primary keys and im using mysql
here's the code i was trying to do :
INSERT INTO table_b SET food = :food, drink = :drink, ( user_id) SELECT a.id FROM table_a u WHERE EXISTS (SELECT * WHERE name = :name AND password = :password)
i know the query is wrong but thats the closest i can do. pls help thank you
You should just use a unique code to link them together.
you can have the code stored in a variable like this
$unique = time().rand(1000, 9999);
//You should have something like this 16659154332358
Create a column that will recieve this value in your database.
Now they have a relationship

Two foreign keys reference one table and null able foreign key

I am new to Database tables and relationships .I need some help for the below requirements
Work flow
1. Hospital will have Male Patient
2. Hospital will have Female Patient
3. Hospital Will have Couple Patient but in RegTable it will stored as separate record for male and female.
For the above requirements i have designed the table structure below
Approach 1
RegTable
+-------+---------+---------+
| RegID | Name | Gender |
+-------+---------+---------+
| 1 | XXX | M |
| 2 | XXX | M |
| 3 | Husband | M |
| 4 | Wife | F |
+-------+---------+---------+
RegDetail
+----+------+-------+
| Id | FK_1 | FK_2 |
+----+------+-------+
| 1 | 1 | Null |
| 2 | 2 | Null |
| 3 | 3 | 4 |
+----+------+-------+
FK_1,FK_2 is RegId from Regtable
I have two questions
Is my current approach is correct or Not ?
Is alternative approach is there for the above work flow .
Kindly help me solve this . Thanks in Advance
You don't need 2 tables here.You can do it as shown below.
RegTables - this is the only table you need
Id int PK
Name string
Gender String
PatientType tinyint
Here you can maintain enum Type for separating Single and couple.
public enum PatientType : byte
{
Single=1,
Couple =2,
}
Update :
Treatments table
Id int PK
Name string
RegId int FK --> this is the foreign key referencing RegTables table
I would suggest the third table RegRecords with field
id, note, date. It will contain a registration data without link to RegTable. So you will store links to real people in RegDetail that will have only two fields: FK_KEY_RegRecords and FK_KEY_ RegTable.

Mysql: Change set column on update condition?

I'm trying to figure out the best way to update one of two fields in a table. I have a personrelationship table and it links two people and I would like to have each person be able to set the relationship type on their end.
PersonRelationship Table
id int
user1_id int
user2_id int
user1_reltype /* boss, manager, etc */
user2_reltype
Depending on whether the current user is either user1_id or user2_id in the table, I need to update the user_reltype accordingly. So basically if current userid is in the user1_id field then update user1_reltype otherwise update the user2_reltype.
Since you want each user to be able to independently manage their half of the relationship, you can simplify your table structure
--------------------------------------
| initiator_id | reltype | target_id |
When a person with ID 5 (the 'initiator') marks person with ID 9 (the 'target') as a friend, the table will contain:
---------------------------------------
| initiator_id | reltype | target_id |
+--------------+----------+-----------+
| 5 | 'friend' | 9 |
If person 9 later initiates a 'boss' connection with person 5, the entry can be created without interfering with the row previously created by person 5:
--------------------------------------
| initiator_id | reltype | target_id |
+--------------+---------+_----------+
| 9 | 'boss' | 5 |
This approach will make your table easy to read and your queries easy to write.
Extra:
If you do not already have it, consider creating another table to track relationship types ('reltype'):
-----------------
| id | type |
+----+----------+
| 1 | 'friend' |
| 2 | 'boss' |
and replace the string reltype's in the relationship table with foreign keys.
---------------------------------------
| initiator_id | reltype | target_id |
+--------------+----------+-----------+
| 5 | 1 | 9 |
| 9 | 2 | 5 |

SQL commands for two tables, which need primary and foreign key

I have table structures as follows:
Table Person :
+-------+--------+
| sno | sname |
+-------+--------+
| 1 | Bhanu |
| 2 | Raghu |
| 3 | Bunny |
| 4 | Shyam |
+-------+--------+
Table Friend :
+------+---------+
| sno | Friend |
+------+---------+
| 1 | 2 |
| 2 | 1 |
| 3 | 4 |
| 4 | 3 |
+------+---------+
Bhanu is friend of Raghu, vice versa.
Bunny is friend of Shyam, vice versa.
If I give the 'Bhanu' name from person table, I should be able to get his friend name as well. Which is mentioned in Friend table with respect to his sno values from person table.
Please do help me in performing this read operation with this kind of database.
You'll need to access the person table twice, and so will need aliases. I suggest this table structure first:
person (id, name)
friend (from_person_id, to_person_id)
This is much the same as your table structure, but the names are a bit clearer.
Now you could have something like:
SELECT
p2.name
FROM
friend
INNER JOIN person p1 ON (p1.id = friend.from_person_id)
INNER JOIN person p2 ON (p2.id = friend.to_person_id)
WHERE
p1.name = 'Bhanu'
;
That lists all the friendships going from "from" to "to". You might additionally want to list all the friendships going the other way, in which case you could add OR p2.name = 'Bhanu'.

MySQL: how to convert to EAV - Part 3?

Previous Related Posts:
MySQL: how to convert to EAV?
MySQL: how to convert to EAV - Part 2?
Given a table:
TABLE: foo
===============================
| id | first_name | last_name |
===============================
| 1 | John | Doe |
| 2 | Jane | Smith |
| 3 | Ronald | McDonald |
-------------------------------
How do I take this table and convert it to these tables (an EAV implementation)?:
TABLE: attribute
===========================
| id | fk_id | attribute |
===========================
| 1 | 100 | first_name |
| 2 | 100 | last_name |
---------------------------
TABLE: value
=========================================
| id | attribute_id | row_id | value |
=========================================
| 1 | 1 | 1 | John |
| 2 | 2 | 1 | Doe |
| 3 | 1 | 2 | Jane |
| 4 | 2 | 2 | Smith |
| 5 | 1 | 3 | Ronald |
| 6 | 2 | 3 | McDonald |
-----------------------------------------
NOTES:
attribute.fk_id will be provided.
value.row_id is used to identify how the values are grouped as records in the original table.
UPDATE: Also, how do I query the EAV tables so that I can make it look like table foo again.
I give +1 to #Phil's solution for populating the EAV table. Insert one attribute at a time.
Here's another solution to reverse an EAV transformation:
SELECT v.row_id AS id,
MAX(IF(a.attribute='first_name',v.value,NULL)) AS first_name,
MAX(IF(a.attribute='last_name',v.value,NULL)) AS last_name
FROM value v INNER JOIN attribute a
ON v.attribute_id = a.id
GROUP BY v.row_id
Except that by using EAV, you've put all your values into a column of VARCHAR(255) or whatever, so you have lost information about the respective data types of the original columns.
There's really no way to do it "dynamically" without hard-coding the attribute names, either as joins as #Phil shows, or as columns as I show. It's essentially the same problem as trying to write dynamic pivot queries.
I have written more about EAV in my presentation Practical Object-Oriented Models in SQL and in my book, SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming.
I think your only hope is if you use the foo table. bar is essentially useless without the ID.
Try something like this (assuming attribute.id is an auto-increment primary key)
INSERT INTO `attribute` (`fk_id`, `attribute`)
VALUES (100, 'first_name');
INSERT INTO `value` (`attribute_id`, `row_id`, `value`)
SELECT LAST_INSERT_ID(), `id`, `first_name`
FROM `foo`;
INSERT INTO `attribute` (`fk_id`, `attribute`)
VALUES (100, 'last_name');
INSERT INTO `value` (`attribute_id`, `row_id`, `value`)
SELECT LAST_INSERT_ID(), `id`, `last_name`
FROM `foo`;
To reconstruct the foo table, try this
SELECT
`fn`.`row_id` AS `id`,
`fn`.`value` AS `first_name`,
`ln`.`value` AS `last_name`
FROM `value` `fn`
INNER JOIN `attribute` `fn_a`
ON `fn`.`attribute_id` = `fn_a`.`id`
AND `fn_a`.`attribute` = 'first_name'
INNER JOIN `value` `ln`
ON `fn`.`row_id` = `ln`.`row_id`
INNER JOIN `attribute` `ln_a`
ON `ln`.`attribute_id` = `ln_a`.`id`
AND `ln_a`.`attribute` = 'last_name'
Ergh, thanks for reminding me why I hate this pattern