Need help in merging three tables foreign keys - mysql

I have created three tables like this,
1.
CREATE TABLE person (
id int NOT NULL AUTO_INCREMENT,
name varchar(50) NOT NULL,
age int,
PRIMARY KEY (id)
);
2.
CREATE TABLE address (
id int NOT NULL AUTO_INCREMENT,
city varchar(50) NOT NULL,
post_code int NOT NULL,
person_id int NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (person_id) REFERENCES person(id)
);
3
CREATE TABLE subjects (
id int NOT NULL AUTO_INCREMENT,
subjects_s varchar(50) NOT NULL,
address_id int NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (address_id) REFERENCES address(id)
);
Now in tables i have some informations like this:
person
+----+--------+------+
| id | name | age |
+----+--------+------+
| 1 | Sohan | 17 |
| 2 | Farhan | 18 |
+----+--------+------+
address
+----+-------+-----------+-----------+
| id | city | post_code | person_id |
+----+-------+-----------+-----------+
| 1 | Tongi | 1711 | 1 |
| 2 | Dhaka | 1230 | 2 |
+----+-------+-----------+-----------+
subjects
+----+--------------------+------------+
| id | subjects_s | address_id |
+----+--------------------+------------+
| 1 | Accounting Finance | 1 |
| 2 | Physics Math | 2 |
+----+--------------------+------------+
Now I want to show all these data together. How can I do this? Please help!

You should be able to use a SQL join statement to combine these.
The syntax is detailed in the MySQL join documentation.
With your tables, your query should look something like this:
SELECT person.*, address.*, subjects.*
FROM person
JOIN address ON person.id = address.person_id
JOIN subjects ON address.id = subjects.address_id
Keep in mind, this example uses an inner join, which may not be the right type of join depending on the data in your tables. I'd recommend reading the documentation I linked above for further guidance.

Related

how to call and connect 1 table with 2 many to many table

so I have this database
ALTER TABLE `Partcar` (
`partcarID` Char(7) NOT NULL,
`partcar_price` decimal(19,4) DEFAULT NULL,
`partcar_name` varchar(100) DEFAULT NULL,
`carIDFK` int(10) NOT NULL,
PRIMARY KEY (`PartcarID`)
UNIQUE KEY `car` (`carID`)
CONTRAINT carIDFK FOREIGN KEY (`carIDK`) REFERENCES car(`carID`)
);
CREATE TABLE `car` (
`carID` Char(7) NOT NULL,
`name_car` varchar(100) DEFAULT NULL,
`car_price` decimal(19,4) DEFAULT NULL,
PRIMARY KEY (`PCID`)
);
ALTER TABLE `assembly` (
`assemblyID` char(8) NOT NULL,
`assembly_price` decimal(19,4) DEFAULT NULL,
`partcarIDFK` int(10) NOT NULL,
`barbellIDFK` int(10) NOT NULL,
PRIMARY KEY (`assemblyID`),
UNIQUE KEY `partcar` (`partcarIDFK`),
UNIQUE KEY `barbell` (`barbellIDFK`),
CONSTRAINT `partcarIDFK` FOREIGN KEY (`partcarIDFK`) REFERENCES partcar(`partcarID`),
CONSTRAINT barbellIDFK FOREIGN KEY (`barbellIDFK`) REFERENCES barbell(`barbellID`)
);
ALTER TABLE `barbell` (
`barbellID` char(10) NOT NULL,
`name_barbell` varchar(100) DEFAULT NULL,
`carIDFK` int(10) NOT NULL,
PRIMARY KEY (`barbellID`),
UNIQUE KEY `car` (`carID`),
CONTRAINT carIDFK FOREIGN KEY (`carIDK`) REFERENCES car(`carID`)
);
So, with this 3 tables, im confused how to connect 3 of them and im thinking with barbell and partcar make Many-to-many relationship with assembly,
so this is the sample of value
assembly and car output
| Code Car(CarID) + Assembly |
-------------------------
| C1234 - B123456 |
that code is a link to see the part.
car + part output
| No. | IDcar + IDpart | Description | Price |
----------------------------------------------
| 1 | C1234 - A333 | Interior | $1 |
| 2 | C1234 - B444 | Chassis | $2 |
and about barbell output
| No. | IDcar | ID Barbell | Description | Price |
-----------------------------------------------------
| 1 | C1234 | 1234-1111 | Big Wheel | $1 |
| 2 | C1234 | 1234-2222 | Wide Wheel | $2 |
OR
assembly and car output
| Code Car + Assembly | ID Partcar, ID barbell | Description | Qty
-----------------------------------------------------------------------
| C1234 - B123456 | | 96' Cougar |
| A333 | Interior | 1
| B444 | Chassis | 1
| 1234-1111 | Big Wheels | 1
| 1234-2222 | Wide Wheels | 1
this is the table, so I just want to know, what relationship to make this and how to call them with PHP?
*description is name of car, part, and barbell. and code car is carID
*note : dont worry about the tables, I just want to know how to connect them and how to call it if the tables like this.

MySQL indexing to efficiently query table join with many to many relationship

I've been struggling to create the correct index to improve performance for a specific query we run on our database, I hope one of you can help point me in the right direction.
I have 2 tables as per below. I have a query to find all employees of companies that belong to a specific category with first_name like "Be%" for example. I've tried creating a multiple index on category_id, company_id but this hasn't helped. What should be the correct way to index my tables to achieve better performance for this query? Thank you in advance.
SELECT
e.*
FROM employee e
INNER JOIN company c ON e.company_id = c.company_id
WHERE c.category_id = 6
AND e.first_name LIKE "Be%"
GROUP BY e.employee_id
TABLE company
| company_id | category_id |
+------------+-------------+
| ... | ... |
+------------+-------------+
| 47 | 6 |
+------------+-------------+
| .. | ... |
+------------+-------------+
| 252 | 6 |
+------------+-------------+
TABLE employee
| employee_id | company_id | first_name | ... |
+-------------+------------+------------+-----+
| 2582250 | 47 | Ben | ... |
+-------------+------------+------------+-----+
| 3447890 | 252 | Ryan | ... |
+-------------+------------+------------+-----+
| 7125966 | 252 | Beth | ... |
+-------------+------------+------------+-----+
| ... | ... | ... | ... |
+-------------+------------+------------+-----+
CREATE TABLES below and sqlfiddle.
CREATE TABLE company (
`company_id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`category_id` INT UNSIGNED NOT NULL DEFAULT 0
) ENGINE=InnoDB;
CREATE TABLE employee (
`employee_id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`company_id` INT UNSIGNED NOT NULL,
`first_name` VARCHAR(255)
) ENGINE=InnoDB;
You must have indexes in many:many tables. Follow the advice outlined here.
WHERE c.category_id = 6
AND e.first_name LIKE "Be%"
needs
c: INDEX(category_id, company_id) -- which will be called for in the link above
e: INDEX(first_name, employee_id)
The Optimizer will either start with c, then reach into e. Or vice versa. I am providing you the optimal indexes for either direction.

MySQL Sort By Column, Then Pull The Rest

I have a unique situation where I need to pull many records, but sort SOME at the top if they are considered "favorites"...but then I need to pull all the rest of the records below this group.
Can this be done in one query...or will I need two? Any examples?
You can have a custom Order By with a CASE/WHEN clause:
Schema:
create table music
( mId int auto_increment primary key,
song varchar(100) not null
);
create table person
( pId int auto_increment primary key,
pName varchar(100) not null
);
create table person_owns_music
( id int auto_increment primary key,
mId int not null,
pId int not null,
favorite int not null,
rating int not null, -- 100 loves it. 0 hates it
foreign key `pom_2_music` (mId) references music(mId),
foreign key `pom_2_person` (pId) references person(pId)
);
-- truncate table person_owns_music;
insert music(song) values ('s1'),('s2'),('s3'),('s4'),('s5'),('s6');
insert person(pName) values ('p1'),('p2'),('p3');
insert person_owns_music(mId,pId,favorite,rating) values
(1,1,1,10),(2,1,1,100),(3,1,0,65),(4,1,1,15),(6,1,1,5),
(1,2,1,10),(2,2,1,100),(5,2,1,100);
Query:
SELECT pom.mId,m.song,pom.favorite,pom.rating
FROM person_owns_music pom
JOIN music m ON m.mId=pom.mId
WHERE pom.pId=1
ORDER BY CASE pom.favorite
WHEN 1 THEN 1
WHEN 0 THEN 2
END, pom.rating DESC;
+-----+------+----------+--------+
| mId | song | favorite | rating |
+-----+------+----------+--------+
| 2 | s2 | 1 | 100 |
| 4 | s4 | 1 | 15 |
| 1 | s1 | 1 | 10 |
| 6 | s6 | 1 | 5 |
| 3 | s3 | 0 | 65 |
+-----+------+----------+--------+

Mysql query of multiple tables joined

I have the following tables:
machine_machine
id | machineid
1 | EE100034442
item_item
id | upc | name
2 | 10001 | Snickers
machine_setup
id | machine_id | selection | item_id
3 | 1 | A1 | 1
Im trying to get the following output by joining the tables.
machine_setup.machine_id=machine_machine.machineid, machine_setup.selection, item_item.upc, item_item.name
EE100034442 A1 10001 Snickers
Table machine_setup will by the main referenced table as it has multiple selection for each machine_id.
Based on the only id's I can see at the moment to join on, consider this:
create table machine_machine
( id int auto_increment primary key,
machineid varchar(50) not null
);
create table item_item
( id int auto_increment primary key,
upc varchar(30) not null,
name varchar(100) not null
);
create table machine_setup
( id int auto_increment primary key,
machine_id int not null,
selection varchar(30) not null
);
insert machine_machine(machineid) values ('EE100034442');
insert item_item(upc,name) values ('10001','Snickers');
insert machine_setup(machine_id,selection) values (1,'A1'),(1,'A2'),(1,'A(n)');
select mm.machineid,ms.selection,ii.upc,ii.name
from machine_setup ms
join machine_machine mm
on mm.id=ms.machine_id
join item_item ii
on ii.id=ms.machine_id;
+-------------+-----------+-------+----------+
| machineid | selection | upc | name |
+-------------+-----------+-------+----------+
| EE100034442 | A1 | 10001 | Snickers |
| EE100034442 | A2 | 10001 | Snickers |
| EE100034442 | A(n) | 10001 | Snickers |
+-------------+-----------+-------+----------+
I'm not quite sure I understand the question, but the sql you want is like;
Select machine1.machineid, setup.Selection, item.upc, item.name
From Machine_machine machine1 --Set alias for the table
Inner Join machine_setup setup on setup.machine_id = machine1.id --This looks like a link table to me
Inner Join item_item item on setup.item_id = item.id -- in your example this wouldn't link as item_id is 1 in the machine_setup
In your example the machine_setup item_id is set to 1, which means it wouldn't link to the item_item table. i'm assuming this is a mistake.
Let me know if you need more information.

MySQL CONCAT multiple unique rows

So, here's basically the problem:
For starter, I am not asking anyone to do my homework, but to just give me a nudge in the right direction.
I have 2 tables containing names and contact data for practicing
Let's call these tables people and contact.
Create Table for people:
CREATE TABLE `people` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`fname` tinytext,
`mname` tinytext,
`lname` tinytext,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Create Table for contact:
CREATE TABLE `contact` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`person_id` int(10) unsigned NOT NULL DEFAULT '0',
`tel_home` tinytext,
`tel_work` tinytext,
`tel_mob` tinytext,
`email` text,
PRIMARY KEY (`id`,`person_id`),
KEY `fk_contact` (`person_id`),
CONSTRAINT `fk_contact` FOREIGN KEY (`person_id`) REFERENCES `people` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
When getting the contact information for each person, the query I use is as follows:
SELECT p.id, CONCAT_WS(' ',p.fname,p.mname,p.lname) name, c.tel_home, c.tel_work, c.tel_mob, c.email;
This solely creates a response like:
+----+----------+---------------------+----------+---------+---------------------+
| id | name | tel_home | tel_work | tel_mob | email |
+----+----------+---------------------+----------+---------+---------------------+
| 1 | Jane Doe | 1500 (xxx-xxx 1500) | NULL | NULL | janedoe#example.com |
| 2 | John Doe | 1502 (xxx-xxx 1502) | NULL | NULL | NULL |
| 2 | John Doe | NULL | NULL | NULL | johndoe#example.com |
+----+----------+---------------------+----------+---------+---------------------+
The problem with this view is that row 1 and 2 (counting from 0) could've been grouped to a single row.
Even though this "non-pretty" result is due to corrupt data, it is likely that this will occur in a multi-node database environment.
The targeted result would be something like
+----+----------+---------------------+----------+---------+---------------------+
| id | name | tel_home | tel_work | tel_mob | email |
+----+----------+---------------------+----------+---------+---------------------+
| 1 | Jane Doe | 1500 (xxx-xxx 1500) | NULL | NULL | janedoe#example.com |
| 2 | John Doe | 1502 (xxx-xxx 1502) | NULL | NULL | johndoe#example.com |
+----+----------+---------------------+----------+---------+---------------------+
Where the rows with the same id and name are grouped when still showing the effective data.
Side notes:
innodb_version: 5.5.32
version: 5.5.32-0ubuntu-.12.04.1-log
version_compile_os: debian_linux-gnu
You could use GROUP_CONCAT(), which "returns a string result with the concatenated non-NULL values from a group":
SELECT p.id,
GROUP_CONCAT(CONCAT_WS(' ',p.fname,p.mname,p.lname)) name,
GROUP_CONCAT(c.tel_home) tel_home,
GROUP_CONCAT(c.tel_work) tel_work,
GROUP_CONCAT(c.tel_mob ) tel_mob,
GROUP_CONCAT(c.email ) email
FROM my_table
GROUP BY p.id