How do I join three fields from three tables in MySQL? - mysql

I have three fields from three different tables that I would like to join together.
company FROM company,
title FROM jobs,
Description FROM jobcategory
I would like to have these three fields join together and listed sequentially to the right of the prvious field as follows:
Company | Title | Description
This is the best I can do as for providing information regarding the databases Keys...
CREATE TABLE `company` (
`companyID` int(11) NOT NULL AUTO_INCREMENT,
`company` varchar(255) NOT NULL,
PRIMARY KEY (`companyID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=117 ;
CREATE TABLE `jobcategory` (
`JobCategoryID` int(11) NOT NULL AUTO_INCREMENT,
`CategoryName` text,
`Description` text,
PRIMARY KEY (`JobCategoryID`),
UNIQUE KEY `unique_JobCategoryID` (`JobCategoryID`),
KEY `index_JobCategoryID` (`JobCategoryID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ;
CREATE TABLE `jobs` (
`title` varchar(255) NOT NULL,
`company` varchar(255) NOT NULL,
`date` date NOT NULL,
`companyID` int(11) NOT NULL,
`jobCategoryID` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
I tried running a query commented below, I received the following error.
"Error 1054 (42S22) : Unknown column 'Company.ID' in "on clause'
What is the proper syntax to execute this query?

Depends on how your keys are set up, but assuming JOBS has foreign keys referencing the COMPANY and JOBCATEGORY tables:
SELECT COMPANY.COMPANY, JOBS.TITLE, JOBCATEGORY.DESCRIPTION<br>
FROM COMPANY
INNER JOIN JOBS ON COMPANY.ID=JOBS.COMPANY_ID
INNER JOIN JOBCATEGORY ON JOBCATEGORY.ID=JOBS.JOBCATEGORY_ID

Related

Mysql Movie Database

I'm creating a movie database and I think I have finished designing it, but my results are not coming back as I would like them too. I only have 2 movies details in the database right now. I'm trying to get it to stop displaying duplicate information.
Can you take a look and give feedback?
Thanks for the help in advance.
/*
Navicat MySQL Data Transfer
Source Server : localhost
Source Server Version : 50525
Source Host : localhost
Source Database : MovieDB
Target Server Version : 50525
File Encoding : utf-8
Date: 09/12/2013 22:06:21 PM
*/
SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for `FORMAT`
-- ----------------------------
DROP TABLE IF EXISTS `FORMAT`;
CREATE TABLE `FORMAT` (
`ID` int(10) NOT NULL AUTO_INCREMENT,
`Formats` varchar(10) NOT NULL DEFAULT '',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for `FORMAT_ID`
-- ----------------------------
DROP TABLE IF EXISTS `FORMAT_ID`;
CREATE TABLE `FORMAT_ID` (
`MovieID` int(11) NOT NULL DEFAULT '0',
`FormatID` int(11) NOT NULL DEFAULT '0',
`Num_Discs` int(128) DEFAULT NULL,
`Locations` varchar(128) DEFAULT NULL,
PRIMARY KEY (`MovieID`,`FormatID`),
KEY `FormatID` (`FormatID`),
CONSTRAINT `FORMAT_ID_ibfk_1` FOREIGN KEY (`MovieID`) REFERENCES `MOVIE` (`ID`),
CONSTRAINT `FORMAT_ID_ibfk_2` FOREIGN KEY (`FormatID`) REFERENCES `FORMAT` (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for `GENRE`
-- ----------------------------
DROP TABLE IF EXISTS `GENRE`;
CREATE TABLE `GENRE` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Genres` varchar(50) NOT NULL DEFAULT '',
`Descriptions` varchar(128) DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=39 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for `GENRE_ID`
-- ----------------------------
DROP TABLE IF EXISTS `GENRE_ID`;
CREATE TABLE `GENRE_ID` (
`MovieID` int(11) NOT NULL DEFAULT '0',
`GenreID` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`MovieID`,`GenreID`),
KEY `GenreID` (`GenreID`),
CONSTRAINT `GENRE_ID_ibfk_2` FOREIGN KEY (`GenreID`) REFERENCES `GENRE` (`ID`),
CONSTRAINT `GENRE_ID_ibfk_1` FOREIGN KEY (`MovieID`) REFERENCES `MOVIE` (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for `MOVIE`
-- ----------------------------
DROP TABLE IF EXISTS `MOVIE`;
CREATE TABLE `MOVIE` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Titles` varchar(128) NOT NULL DEFAULT '',
`Alt_Titles` varchar(128) DEFAULT NULL,
`Types` varchar(10) NOT NULL DEFAULT '',
`Synopsis` varchar(128) DEFAULT NULL,
`Images` varchar(128) DEFAULT NULL,
`Num_Eps` int(10) DEFAULT '0',
`Catagories` varchar(50) NOT NULL DEFAULT '',
`Duration` time DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for `RENT`
-- ----------------------------
DROP TABLE IF EXISTS `RENT`;
CREATE TABLE `RENT` (
`MovieID` int(11) NOT NULL DEFAULT '0',
`Rents` varchar(3) NOT NULL DEFAULT '',
`Who` varchar(128) NOT NULL DEFAULT '',
`Note` varchar(128) DEFAULT NULL,
PRIMARY KEY (`MovieID`,`Rents`,`Who`),
CONSTRAINT `RENT_ibfk_1` FOREIGN KEY (`MovieID`) REFERENCES `MOVIE` (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
SET FOREIGN_KEY_CHECKS = 1;
sql:
select distinct Titles, Types, Num_Eps, Catagories, Duration, Formats, Num_Discs, Genres
from MOVIE, FORMAT, FORMAT_ID, GENRE, GENRE_ID
where MOVIE.ID=GENRE_ID.MovieID
AND GENRE_ID.GenreID=GENRE.ID
and MOVIE.ID=FORMAT_ID.MovieID
AND FORMAT_ID.FormatID=FORMAT.ID
order by Titles;
this is my results:
Titles,Types,Num_Eps,Catagories,Duration,Formats,Num_Discs,Genres
Ghost in the Shell,Movie,1,Anime,01:23:00,DVD,1,Mecha
Ghost in the Shell,Movie,1,Anime,01:23:00,DVD,1,Police
Ghost in the Shell,Movie,1,Anime,01:23:00,DVD,1,Psychological
Ghost in the Shell,Movie,1,Anime,01:23:00,DVD,1,Sci-Fi
Ghost in the Shell,Movie,1,Anime,01:23:00,DVD,1,Cyberpunk
Ghost in the Shell,Movie,1,Anime,01:23:00,Bluray,1,Mecha
Ghost in the Shell,Movie,1,Anime,01:23:00,Bluray,1,Police
Ghost in the Shell,Movie,1,Anime,01:23:00,Bluray,1,Psychological
Ghost in the Shell,Movie,1,Anime,01:23:00,Bluray,1,Sci-Fi
Ghost in the Shell,Movie,1,Anime,01:23:00,Bluray,1,Cyberpunk
Summer Wars,Movie,1,Anime,01:54:00,DVD,1,Comedy
Summer Wars,Movie,1,Anime,01:54:00,DVD,1,Sci-Fi
Summer Wars,Movie,1,Anime,01:54:00,HD,,Comedy
Summer Wars,Movie,1,Anime,01:54:00,HD,,Sci-Fi
A few points. I would use full join syntax,
FROM MOVIE JOIN GENRE ON MOVIE.ID=GENRE_ID.MovieID
instead of the where clauses you have now.
Then you might want to try GROUP_CONCAT(expr) to concatenate your Genres into one line, ex. Mecha, Police, Psychological, etc...
Update: Thanks to Vulcronos I got genres and formats to list out right if I do them separate by using
Genre:
select distinct Titles, Types, Num_Eps, Catagories, Duration, Genres
FROM MOVIE JOIN GENRE_ID ON MOVIE.ID=GENRE_ID.MovieID, GENRE
where GENRE_ID.GENREID=GENRE.ID
order by Titles;
format:
select distinct Titles, Types, Num_Eps, Catagories, Duration, Formats, Num_Discs, Locations
FROM MOVIE JOIN FORMAT_ID ON MOVIE.ID=FORMAT_ID.MovieID, FORMAT
where FORMAT_ID.FORMATID=FORMAT.ID
order by Titles;
Is there any way to combine the two?
So I would get something like this:
Ghost in the Shell,Movie,1,Anime,01:23:00,DVD,1,Mecha
Ghost in the Shell,Movie,1,Anime,01:23:00,DVD,1,Police
Ghost in the Shell,Movie,1,Anime,01:23:00,DVD,1,Psychological
Ghost in the Shell,Movie,1,Anime,01:23:00,DVD,1,Sci-Fi
Ghost in the Shell,Movie,1,Anime,01:23:00,Bluray,1,Cyberpunk
Summer Wars,Movie,1,Anime,01:54:00,DVD,1,Comedy
Summer Wars,Movie,1,Anime,01:54:00,HD,,Sci-Fi
Where it would list the genres once and the formats once. Of course with multiple genres the format will be repeated unless there is a way to fix that, but where it will at least show all the formats once along with genres once.
Thanks for the help.
Nobody is probably looking at this thread any more, but I wanted to let future views and the people who helped me that I found what I was looking for in the question.
select DISTINCT m.Title,
group_concat(DISTINCT g.Genre) as Genres,
group_concat(DISTINCT f.Format) as Formats
from MOVIES m
left join MOVIEGENRES mg on m.Code=mg.MovieCode
left join GENRES g on mg.GenCode=g.Code
left join MOVIEFORMATS mf on m.Code=mf.MovieCode
left join FORMATS f on mf.FormCode=f.Code
group by m.Code;

chaning the join in mysql

I have 2 tables, faq and faq_categories...i have a join that work, and so far, I was a happy camper.
But...requirements change, and i have to change the join, but i don't know how to do it
Here is the current code that works just fine:
SELECT faq.* , faq_categories.categoryname
FROM faq
JOIN faq_categories
ON ( faq.catid = faq_categories.catid)
So far, all faq belongs to one category...but from now on, there will be faq which will not belonng to any category....and that complicate things, at least for me.
How should I change this code in order to display the faq which does not have catid?
Here are my tables:
CREATE TABLE IF NOT EXISTS `faq_categories` (
`catid` int(11) NOT NULL AUTO_INCREMENT,
`parentid` int(11) DEFAULT NULL,
`categoryname` varchar(255) NOT NULL,
`categoryname_en` varchar(255) DEFAULT NULL,
`description` text,
`description_en` text,
`metatags` text,
`metatags_en` text,
`sorder` int(11) NOT NULL,
`visible` tinyint(4) NOT NULL,
`categoryphoto` varchar(255) DEFAULT '',
PRIMARY KEY (`catid`),
KEY `parentid_fk` (`parentid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=204 ;
CREATE TABLE IF NOT EXISTS `faq` (
`faqid` int(11) NOT NULL AUTO_INCREMENT,
`catid` int(11) DEFAULT NULL,
`question` text NOT NULL,
`question_en` text NOT NULL,
`answer` text,
`answer_en` text,
`metatags` text,
`metatags_en` text,
`sorder` tinyint(4) DEFAULT NULL,
`visible` tinyint(4) DEFAULT NULL,
PRIMARY KEY (`faqid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;
For those that have no category, we assume you mean faq.catid will be NULL. Your table definitions don't need to change at all. That will only require changing yourINNER JOINto aLEFT JOIN. The FAQs with no category will show aNULLforfaq_categories.categoryname` in the output:
SELECT
faq.* ,
faq_categories.categoryname
FROM
faq
LEFT JOIN faq_categories ON ( faq.catid = faq_categories.catid)
I would encourage you now to anticipate the time when a FAQ must belong to more than one category, however. To do that, you need to create a joining table which contains a faqid and catid. There can be many rows per faqid:
CREATE TABLE faq_in_categories (
faqid INT(11) NOT NULL,
catid INT(11) NOT NULL,
PRIMARY KEY (faqid, catid),
FOREIGN KEY (faqid) REFERENCES faq (faqid),
FOREIGN KEY (catid) REFERENCES faq_categories (catid)
);
Under this model, you would remove the faq.catid column because membership in a category is defined in the joining table. This is a many-to-many relationship.
Queried by:
SELECT
faq.*
categories.*
FROM
faq
JOIN faq_in_categories ON faq.faqid = faq_in_categories.faqid
JOIN categories ON faq_in_categories.catid = categories.catid
WHERE faq.faqid = 'some faqid'

How to query on a three mysql joined table?

I have three mysql table:
*page_category* table
CREATE TABLE `page_category` (
`id_page` VARCHAR(255) NOT NULL,
`name` VARCHAR(255) DEFAULT NULL,
`search_here` TEXT,
PRIMARY KEY (`id_page`),
FULLTEXT KEY `search` (`search_here`)
) ENGINE=MYISAM DEFAULT CHARSET=latin1
*page_category* table contains more than 2 million rows of data.
*user_page* table
CREATE TABLE `user_page` (
`user_id` VARCHAR(255) NOT NULL,
`id_page` VARCHAR(255) NOT NULL,
PRIMARY KEY (`user_id`,`id_page`)
) ENGINE=INNODB DEFAULT CHARSET=latin1
*user_page* table contains more than 10 million rows of data.
*user_relationship* table
CREATE TABLE `user_relationship` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`me` VARCHAR(255) DEFAULT NULL,
`friend` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `me_friend` (`me`,`friend`)
) ENGINE=INNODB AUTO_INCREMENT=7517967 DEFAULT CHARSET=latin1
*user_relationship* table contains more than 1 million rows of data.
I do a query:
SELECT a.id_page AS ids, b.user_id,
a.name AS nama, c.me,
COUNT(c.me) AS nfriend,
GROUP_CONCAT(b.user_id SEPARATOR ',') AS friendlist
FROM
page_category a
LEFT JOIN user_page b
ON a.id_page = b.id_page
LEFT JOIN user_relationship c
ON
b.user_id = c.friend
WHERE
c.me='12' AND
MATCH(a.search_here) AGAINST('+book' IN BOOLEAN MODE);
results are shown in a very long time. am I wrong on writing the query?
You need to add proper indexing as well as you need to make query so that it has less temp. You can change order of join and explain it to debug your query to ger the best one.

How to apply the MINUS efficiently on mysql query for tables with large data

I have 2 tables as the following -
CREATE TABLE IF NOT EXISTS `nl_members` (
`member_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`member_email` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`member_confirmation_code` varchar(35) COLLATE utf8_unicode_ci NOT NULL,
`member_enabled` enum('Yes','No') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'Yes',
PRIMARY KEY (`member_id`),
UNIQUE KEY `TUC_nl_members_1` (`member_email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=58520 ;
CREATE TABLE IF NOT EXISTS `nl_member_group_xref` (
`group_id` int(10) unsigned NOT NULL,
`member_id` int(10) unsigned NOT NULL,
`member_subscribed` enum('Yes','No') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'Yes',
`subscribe_date` int(10) unsigned NOT NULL DEFAULT '0',
`unsubscribe_date` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`group_id`,`member_id`),
KEY `nl_members_nl_member_group_xref` (`member_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
ALTER TABLE `nl_member_group_xref`
ADD CONSTRAINT `nl_members_nl_member_group_xref` FOREIGN KEY (`member_id`) REFERENCES `nl_members` (`member_id`),
ADD CONSTRAINT `nl_member_groups_nl_member_group_xref` FOREIGN KEY (`group_id`) REFERENCES `nl_member_groups` (`group_id`);
Both has quite some large amount of data about millions of them.
What i want is to have an efficient was of applying the MINUS on result set.
For example,
i want to get all the users from Group1 with ID: 1 MINUS all users from Group2 with ID: 2 and Group3 with ID: 3
How can i do it efficiently? with the query running as fast as possible.
Update
What i want is like this -
in members table 'nl_members' i keep a list of all members, who could have been associated with one or more groups.
for each group association for a member there will be a row in the 'nl_member_group_xref' table.
so if a member is associated with 3 groups there will be 3 entries in the member_group_xref table.
Now what i want is to get all members included in group 1 but exclude members if they also belong to group 2 and group 3.
Hope this helps.
For your updated question you will need to join the two tables and group it with members_id: See below query if will display the result your looking for.
UPDATED:
SELECT
nm.*, nmgx.*
FROM nl_members nm
INNER JOIN nl_member_group_xref nmgx
ON nm.member_id = nmgx.member_id
LEFT JOIN (SELECT
nmgx2.member_id
FROM nl_member_group_xref nmgx2
WHERE nmgx2.group_id <> 1) nmgx22
ON nmgx22.member_id = nm.member_id
WHERE nmgx22.member_id IS NULL
GROUP BY nm.member_id;
Note: I used * to get all the field name. You get specific field so the query will be more faster as it only get less results. Ex. member_id like nm.member_id
If this is not what you looking for, just inform me then I'll update this query as accurate as I can
Have you tried using the MINUS operator?

Optimize Join sentence with foreign keys, and show records with nulls

I have the following structure
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
CREATE TABLE IF NOT EXISTS `sis_param_tax` (
`id` int(5) NOT NULL auto_increment,
`description` varchar(50) NOT NULL,
`code` varchar(5) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7;
CREATE TABLE IF NOT EXISTS `sis_param_city` (
`id` int(4) NOT NULL auto_increment,
`name` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
CREATE TABLE IF NOT EXISTS `sis_supplier` (
`id` int(15) NOT NULL auto_increment,
`name` varchar(200) NOT NULL,
`address` varchar(200) default NULL,
`phone` varchar(30) NOT NULL,
`fk_city` int(11) default NULL,
`fk_tax` int(11) default NULL,
PRIMARY KEY (`id`),
KEY `fk_city` (`fk_city`),
KEY `fk_tax` (`fk_tax`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
ALTER TABLE `sis_supplier`
ADD CONSTRAINT `sis_supplier_ibfk_4` FOREIGN KEY (`fk_tax`) REFERENCES `sis_param_tax` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
ADD CONSTRAINT `sis_supplier_ibfk_3` FOREIGN KEY (`fk_city`) REFERENCES `sis_param_city` (`id`) ON DELETE SET NULL ON UPDATE CASCADE;
My questions are
1. This structure allows me to have a supplier with city and tax fields = null (in case user didn't set these values). Right?
2. If I delete "X" city, supplier's fk_city with city="X" are set to null, same with fk_tax. Right?
3. I want to optimize (IF POSSIBLE) the following join sentence, so I can show suppliers whom have fk_city and/or fk_tax = NULL
SELECT DISTINCT
sis_supplier.id,
sis_supplier.name,
sis_supplier.telefono,
sis_supplier.address,
sis_supplier.phone,
sis_supplier.cuit,
sis_param_city.name AS city,
sis_param_tax.description AS tax,
sis_supplier.fk_city,
sis_supplier.fk_tax
FROM
sis_supplier
LEFT OUTER JOIN sis_param_city
ON
sis_supplier.`fk_city` = sis_param_city.id
LEFT OUTER JOIN `sis_param_tax`
ON
sis_supplier.`fk_tax` = `sis_param_tax`.`id`
Thanks a lot in advance,
Yes.
Yes.
Yes, it's good to optimize. The query you showed looks fine. How is it not working for you?
Have you analyzed the query with EXPLAIN? This can help you tell when you have a query that isn't using indexes effectively. In fact, all of Chapter 7 Optimization would be recommended reading.
if you want to show records with nulls than use RIGHT or LEFT JOIN
depend on your needs