Haris Khan
Haris Khan

Reputation: 355

how to fetch data from multiple tables

So I normalize my database and it seems quite complicated for me to fetch or update records in tables. I have 5 tables ( details, country, materials, vendor_countries, vendor_materials). Actually "details" is my main table.

A vendor could have multiple countries and materials so I made two more tables vendor_countries and vendor_materials and their column are (did,cid), (did,mid). "did" is the id of each vendor coming from details table and cid,mid is the country id and material id coming from country and material table.

Now I want to fetch vendors along with their countries and materials.

here is my details table, vendor_countries and vendor_materials tables

details tablevendor materialvendor country

so far I made a query which is shown below:

select dt.vendor,
       dt.email,
       dt.address,
       c.country,
       m.material,
       c.country
  from country c
       inner join vendor_countries vc on (c.id = vc.cid)
       right join details dt on (dt.id = vc.did)
       left join vendor_materials vm on dt.id = vm.did
       left join material m on vm.mid = m.id

and i am getting results like this:

results

which is not right it should be in 3 rows because "ali" vendor works in 3 countries and 3 materials. I am looking for some smart solution which also not slow down my page. Thanks in advance.

Upvotes: 1

Views: 139

Answers (1)

Professor Abronsius
Professor Abronsius

Reputation: 33823

In the absence of any response regarding table schema I tried to re-create the tables based upon the descriptions above -prefixing each table with v_ so I could group the tables in this db and referencing did as vid ( vendor id ) and populating with what I believed to be the sample data from the question

mysql> describe v_country;
+-------+------------------+------+-----+---------+----------------+
| Field | Type             | Null | Key | Default | Extra          |
+-------+------------------+------+-----+---------+----------------+
| id    | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name  | varchar(50)      | YES  |     | NULL    |                |
+-------+------------------+------+-----+---------+----------------+


mysql> describe v_details;
+---------+------------------+------+-----+---------+----------------+
| Field   | Type             | Null | Key | Default | Extra          |
+---------+------------------+------+-----+---------+----------------+
| id      | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| vendor  | varchar(50)      | YES  |     | NULL    |                |
| email   | varchar(50)      | YES  |     | NULL    |                |
| phone   | varchar(50)      | YES  |     | NULL    |                |
| address | varchar(50)      | YES  |     | NULL    |                |
+---------+------------------+------+-----+---------+----------------+


mysql> describe v_materials;
+-------+------------------+------+-----+---------+----------------+
| Field | Type             | Null | Key | Default | Extra          |
+-------+------------------+------+-----+---------+----------------+
| id    | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name  | varchar(50)      | YES  |     | NULL    |                |
+-------+------------------+------+-----+---------+----------------+


mysql> describe v_vendor_materials;
+-------+------------------+------+-----+---------+----------------+
| Field | Type             | Null | Key | Default | Extra          |
+-------+------------------+------+-----+---------+----------------+
| id    | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| vid   | int(10) unsigned | NO   | MUL | 0       |                |
| mid   | int(10) unsigned | NO   | MUL | 0       |                |
+-------+------------------+------+-----+---------+----------------+


mysql> describe v_vendor_countries;
+-------+------------------+------+-----+---------+----------------+
| Field | Type             | Null | Key | Default | Extra          |
+-------+------------------+------+-----+---------+----------------+
| id    | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| vid   | int(10) unsigned | NO   | MUL | 0       |                |
| mid   | int(10) unsigned | NO   | MUL | 0       |                |
+-------+------------------+------+-----+---------+----------------+






mysql> select * from v_country;
+----+----------+
| id | name     |
+----+----------+
|  1 | pakistan |
|  2 | India    |
|  3 | Iran     |
+----+----------+


mysql> select * from v_details;
+----+--------+------------------+---------------+-----------+
| id | vendor | email            | phone         | address   |
+----+--------+------------------+---------------+-----------+
|  1 | harris | [email protected] | 0141 236 4523 | nowhere   |
|  2 | Boris  | [email protected]  | 0141 451 7845 | somewhere |
|  3 | Doris  | [email protected]  | 0141 353 7845 | anywhere  |
+----+--------+------------------+---------------+-----------+


mysql> select * from v_materials;
+----+---------+
| id | name    |
+----+---------+
|  1 | ceramic |
|  2 | iron    |
|  3 | plastic |
+----+---------+


mysql> select * from v_vendor_materials;
+----+-----+-----+
| id | vid | mid |
+----+-----+-----+
|  1 |   1 |   1 |
|  2 |   2 |   2 |
|  3 |   3 |   3 |
+----+-----+-----+


mysql> select * from v_vendor_countries;
+----+-----+-----+
| id | vid | mid |
+----+-----+-----+
|  1 |   1 |   1 |
|  2 |   2 |   2 |
|  3 |   3 |   3 |
+----+-----+-----+





mysql> select * from v_details d
          left outer join v_vendor_materials vm on vm.vid=d.id
          left outer join v_vendor_countries vc on vc.vid=d.id
          left outer join v_materials m on m.id=vm.id
          left outer join v_country c on c.id=vc.id;

+----+--------+------------------+---------------+-----------+------+------+------+------+------+------+------+---------+------+----------+
| id | vendor | email            | phone         | address   | id   | vid  | mid  | id   | vid  | mid  | id   | name    | id   | name     |
+----+--------+------------------+---------------+-----------+------+------+------+------+------+------+------+---------+------+----------+
|  1 | harris | [email protected] | 0141 236 4523 | nowhere   |    1 |    1 |   1  |    1 |    1 |    1 |    1 | ceramic |    1 | pakistan |
|  2 | Boris  | [email protected]  | 0141 451 7845 | somewhere |    2 |    2 |   2  |    2 |    2 |    2 |    2 | iron    |    2 | India    |
|  3 | Doris  | [email protected]  | 0141 353 7845 | anywhere  |    3 |    3 |   3  |    3 |    3 |    3 |    3 | plastic |    3 | Iran     |
+----+--------+------------------+---------------+-----------+------+------+------+------+------+------+------+---------+------+----------+

or, a more selective query

select 
    d.`id` as `vid`,
    d.`vendor`,
    d.`email`,
    d.`phone`,
    d.`address`,
    m.`name` as `material`,
    c.`name` as `country`
    from v_details d
    left outer join v_vendor_materials vm on vm.vid=d.id
    left outer join v_vendor_countries vc on vc.vid=d.id
    left outer join v_materials m on m.id=vm.id
    left outer join v_country c on c.id=vc.id;


+-----+--------+------------------+---------------+-----------+----------+----------+
| vid | vendor | email            | phone         | address   | material | country  |
+-----+--------+------------------+---------------+-----------+----------+----------+
|   1 | harris | [email protected] | 0141 236 4523 | nowhere   | ceramic  | pakistan |
|   2 | Boris  | [email protected]  | 0141 451 7845 | somewhere | iron     | India    |
|   3 | Doris  | [email protected]  | 0141 353 7845 | anywhere  | plastic  | Iran     |
+-----+--------+------------------+---------------+-----------+----------+----------+

Upvotes: 1

Related Questions