Mysql mapping two table - mysql

How to mapping two table ?
table tableA:
+------------------+-----------------------+------+-----+---------------------+-------------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+-----------------------+------+-----+---------------------+-------------------------------+
| id | int(10) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| price | decimal(8,2) | NO | | NULL | |
+------------------+-----------------------+------+-----+---------------------+-------------------------------+
+------+------------+
| id | name | price |
+------+------------+
12 | foo | 0.12 |
2 | barr | 0.20 |
+------+------------+
table tableB:
+------------+-----------------------+------+-----+---------------------+-------------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-----------------------+------+-----+---------------------+-------------------------------+
| id | int(10) | NO | PRI | NULL | auto_increment |
| user_id | int(10) | NO | | NULL | |
| service_id | int(10) | NO | | NULL | |
| price | decimal(8,2) | NO | | NULL | |
+------------+-----------------------+------+-----+---------------------+-------------------------------+
+------------+------------+
| user_id | service_id | price |
+------------+------------+
| 2 | 12 | 0.01 |
+------------+------------+
When query to get of user mapping. Also like "SELECT price FROM tableA" need returns tableB column value.
Example of result:
+------+------------+
| id | name | price |
+------+------------+
12 | foo | 0.01 |
+------+------------+

What do you really mean by mapping two tables? There are three main mapping methods.
Insert
Update
Delete
I think you can get more idea of visiting these sites.
(http://www.mysqltutorial.org/compare-two-tables-to-find-unmatched-records-mysql.aspx)
(https://help.10web.io/hc/en-us/articles/360016083011-Settings-MySQL-Mapping)

Based on "Example Result" you are trying to link TableA with TableB with id and service_id. In that case, you can achieve the result by running this query
Select ta.id,ta.name,tb.price
from TableA ta,TableB tb Where
ta.id = tb.service_id;
The above query provides the relation for the tables.

Related

Fetching data from three tables?

I have three tables category, brand, product.
Category table -
+---------------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| category_name | varchar(255) | NO | | NULL | |
| category_UID | varchar(255) | NO | UNI | NULL | |
| date | date | YES | | NULL | |
| time | time | YES | | NULL | |
| is_delete | tinyint(1) | YES | | 0 | |
+---------------+--------------+------+-----+---------+----------------+
Brand table -
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| brand_name | varchar(255) | NO | | NULL | |
| brand_UID | varchar(255) | NO | UNI | NULL | |
| fk_id | varchar(255) | NO | | NULL | |
| date | date | NO | | NULL | |
| time | time | NO | | NULL | |
| is_delete | tinyint(1) | YES | | 0 | |
+------------+--------------+------+-----+---------+----------------+
Products -
+-----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| category_UID | varchar(255) | NO | | NULL | |
| brand_UID | varchar(255) | NO | | NULL | |
| product_name | varchar(255) | NO | | NULL | |
| product_UID | varchar(255) | NO | UNI | NULL | |
| keyword | varchar(255) | YES | | NULL | |
| photo | varchar(255) | NO | | NULL | |
| photo_thumbnail | varchar(255) | YES | | NULL | |
| date | date | NO | | NULL | |
| time | time | NO | | NULL | |
| is_delete | tinyint(1) | YES | | 0 | |
| visible | tinyint(1) | YES | | 1 | |
+-----------------+--------------+------+-----+---------+----------------+
In HTML page there is a search type input in which user will type atleast three characters to get the serach result from DB.
How will be search technique -
I want to search for products and grab all their data.
The search string will be find by product_name or keywords from product table.
If the search string doesn't found in product table then the search string may be find by category_name or brand_name from category table or brand table respectively. Now If we get our search then the category_UID must be present in product table. (It means we will get our search only when that category UID stored in product table)
I want to get the output as -
If search success, we must get all the column data from product table including two more columns category_name, brand_name from category table and brand table respectively.
Note :
only one attribute category_UID is common in all three tables.
So How can I get the search for product ?
Is this can be solved by JOIN or UNION technique else I have to use procedural way.
In your table, category_UID and product_UID are the foreign keys references, then the following query will work.
select p.id as id,p.category_UID as category_UID,p.brand_UID as brand_UID,
p.product_name as product_name,p.product_UID as product_UID,p.keyword as keyword,
p.photo as photo,p.photo_thumbnail as photo_thumbnail,p.date as date,p.time as time,
p.is_delete as is_delete,p.visible as visible,c.category_name as category_name, b.brand_name as brand_name
FROM product as p
JOIN Brand as b ON p.brand_UID = b.brand_UID
JOIN category as c ON p.category_UID = c.category_UID
where p.product_name like '%<search_str>%' OR
p.keyword like '%<search_str>%' OR
b.brand_name like '%<search_str>%' OR
c.category_name like '%<search_str>%';

Check that all rows in table A have a specific value in table B, including a GROUP BY

I have two tables - students and evidence - and I'm trying to check for a corresponding value in one column in evidence, grouped by another column in evidence for every entry in students
These are what the tables look like:
> desc students;
+------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| firstname | varchar(191) | NO | | NULL | |
| surname | varchar(191) | NO | | NULL | |
| class_id | int(11) | NO | | NULL | |
| dob | datetime | NO | | NULL | |
| enrollment | datetime | NO | | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
+------------+---------------------+------+-----+---------+----------------+
> desc evidence;
+---------------+------------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+------------------------------------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| type | enum('written','image','audio','video','link') | YES | | NULL | |
| mime | varchar(191) | YES | | NULL | |
| path | varchar(191) | YES | | NULL | |
| user_id | int(11) | NO | | NULL | |
| date_recorded | datetime | YES | | NULL | |
| statement_id | int(11) | NO | | NULL | |
| progress | int(11) | NO | | NULL | |
| notes | mediumtext | YES | | NULL | |
| student | int(11) | NO | MUL | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
+---------------+------------------------------------------------+------+-----+---------+----------------+
Entries in the evidence table are associated with a student (evidence.student_id) and an evidence statement (evidence.statement_id) and then given a progress value of 1 (in progress) or 2 (complete).
I want to be able to check that for each statement_id every student has at least one row with the progress entry set to 2. Ideally I'd like to GROUP BY statement_id and only return a value of 2 for progress if every student has at least one row in the evidence table for that statement_id where progress has been set to 2.
The goal is to list all of the statement_ids where everyone in a class has completed the task (and therefore had some evidence added with progress set to complete).
I've tried doing joins similar to this
SELECT * FROM students left join evidence ON students.id = evidence.student GROUP BY evidence.statement_id HAVING progress = 2;
but the problem there is that if one student is marked as completing a statement_id but another student doesn't have any entries for that statement_id then progress will return 2. I'd rather it just returned NULL for the student without any entries.
I'm pretty stumped on this one to any help is greatly appreciated.

COUNT, Minimum Value per course without subquery

Can anyone help me find the minimum student action per course? Listed like this:
+-------------+--------------------------+
| Course | Lowest Action |
+-------------+--------------------------+
| Maths Y1 | |
| English C | |
| Science Y1 | |
for all users, even if they are not in the log table, without a subquery? My thanks to #luckylwk for assistance with my initial query. I have a solution with a subquery but want to put this into a variable for a much large query.
SELECT
COUNT(tbl_log.action)
lastname,
c.fullname,
FROM tbl_log
JOIN tbl_user ON tbl_log.userid = tbl_user.id
JOIN tbl_course ON tbl_log.course = tbl_course.id
GROUP BY tbl_log.userid, tbl_log.course
LOG TABLE
+-------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------------+------+-----+---------+----------------+
| id | | NO | PRI | NULL | auto_increment |
| time | | NO | | NULL | |
| userid | | NO | | NULL | |
| course | | NO | | NULL | |
| action | | NO | | NULL | |
+-------------+---------------------+------+-----+---------+----------------+
USER Table
+--------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------------+------+-----+---------+----------------+
| id | | NO | PRI | NULL | auto_increment |
| username | | NO | | NULL | |
| userpassword | | NO | | NULL | |
| lastname | | NO | | NULL | |
| firstname | | NO | | NULL | |
+--------------+---------------------+------+-----+---------+----------------+
COURSE table
+--------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------------+------+-----+---------+----------------+
| id | | NO | PRI | NULL | auto_increment |
| category | | NO | | NULL | |
| fullname | | NO | | NULL | |
| shortname | | NO | | NULL | |
+--------------+---------------------+------+-----+---------+----------------+
I link the users together via the enrolment and context tables.
Try:
SELECT
tbl_course.course_name,
MIN(tbl_log.action) as Lowest_Action
FROM tbl_log
JOIN tbl_user ON tbl_log.userid = tbl_user.id
JOIN tbl_course ON tbl_log.course = tbl_course.id
GROUP BY tbl_course.course_name
See Fiddle Demo

MySQL db join query

I am working with an Employee database in Mysql. My Db contains the following tables
mysql> describe edept;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| dept | varchar(20) | NO | | NULL | |
+-------+-------------+------+-----+---------+-------+
mysql>describe esal;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| basic | int(11) | NO | | NULL | |
| pf | int(11) | NO | | NULL | |
+-------+---------+------+-----+---------+-------+
mysql> describe edesig;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| desig | varchar(20) | NO | | NULL | |
+-------+-------------+------+-----+---------+-------+
mysql> select * from edetails inner join edept on edetails.dept=edept.id;
+----+--------+-----+------+-------+-------+----+----+------------------+
| id | name | age | dept | desig | basic | pf | id | dept |
+----+--------+-----+------+-------+-------+----+----+------------------+
| 1 | swetha | 21 | 3 | 2 | 2 | 2 | 3 | Business Process |
+----+--------+-----+------+-------+-------+----+----+------------------+
mysql> describe edetails;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(20) | NO | | NULL | |
| age | int(11) | NO | | NULL | |
| dept | int(11) | NO | MUL | NULL | |
| desig | int(11) | YES | MUL | NULL | |
| basic | int(11) | NO | MUL | NULL | |
| pf | int(11) | NO | MUL | NULL | |
+-------+-------------+------+-----+---------+-------+
I have to get values for dept,desig,basic,pf from the tables edept.dept,edesig.desig,esal.basic,esal.pf respectively.
I used foreign keys for all the fields for which i have to retrieve values from other tables.And i tried a sample inner join query. but i got the output as follows:
mysql> select * from edetails inner join edept on edetails.dept=edept.id;
+----+--------+-----+------+-------+-------+----+----+------------------+
| id | name | age | dept | desig | basic | pf | id | dept |
+----+--------+-----+------+-------+-------+----+----+------------------+
| 1 | swetha | 21 | 3 | 2 | 2 | 2 | 3 | Business Process |
+----+--------+-----+------+-------+-------+----+----+------------------+
My edept table contains the following:
mysql> select * from edept;
+----+------------------+
| id | dept |
+----+------------------+
| 3 | Business Process |
+----+------------------+
How can i eliminate duplicate columns. i need the value "business process" in the dept field of the edept table
Try this::
select
edetails.id,
edetails.name,
edetails.age,
edetails.dept,
edesig.desig,
edetails.basic,
edetails.pf,
edept.dept
from edetails
inner join edept on edetails.dept=edept.id
INNER JOIN edesig on edesig.id=edetails.desig

Help with MySQL join 3 Tables

I am working on a registration system that uses the following tables:
Person (name etc.), Course (course date), Registration (association table pid, cid)
Person
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | text | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
Example Data:
select * from person;
+-----+--------+
| id | name |
+-----+--------+
| 101 | Graham |
| 102 | Lisa |
| 103 | John |
+-----+--------+
Course
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | text | YES | | NULL | |
| date | date | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
select * from course;
+----+---------+------------+
| id | name | date |
+----+---------+------------+
| 1 | Hip Hop | 2011-06-08 |
| 2 | Dancing | 2006-06-23 |
| 3 | Running | 2007-07-08 |
+----+---------+------------+
Registration
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| pid | int(11) | YES | | NULL | |
| cid | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
select * from registration;
+----+------+------+
| id | pid | cid |
+----+------+------+
| 1 | 101 | 1 |
| 2 | 101 | 2 |
| 3 | 103 | 2 |
+----+------+------+
I would like to find person(s) that have no registration records within the past two years. I am attempting to join the tables based on date calculation but it does not seem to work this way. Is this possible with mysql or is my approach of trying this with one query wrong?
query I have come up with:
select * from
(person left join registration on person.id = registration.pid)
left join course on course.id = registration.cid
AND DATE_FORMAT(`course`.`date`, "%m.%Y") > DATE_FORMAT( DATE_SUB(NOW(), INTERVAL 2 YEAR),"%m.%Y")
WHERE
registration.id IS NULL;
+-----+------+------+------+------+------+------+------+
| id | name | id | pid | cid | id | name | date |
+-----+------+------+------+------+------+------+------+
| 102 | Lisa | NULL | NULL | NULL | NULL | NULL | NULL |
+-----+------+------+------+------+------+------+------+
It should list person 102 and 103 since both registrations are older than 2 years and no other records of newer course dates can be found...
Give this a shot, using a NOT EXISTS clause:
select p.* from person p
where not exists (select 1 from person px
join registration rx on px.id = rx.pid
join course cx on rx.cid = cx.id
where px.id = p.id
and cx.date > DATE_SUB(NOW(), INTERVAL 2 YEAR))