Select items from 3 different tables - mysql

I would like to select items from 3 different tables, I am using UNION, but the number of columns is different, so it returns an error of number of columns, is there any other way using JOIN to get an appreciated result?
SELECT *
FROM `ads` JOIN ad_car
ON ads.id_ads = ad_car.main_ad
WHERE ads_cat = :ads_cat AND
ads.ad_status = :adStatus
UNION
SELECT *
FROM `ads` JOIN ad_vehpro
ON ads.id_ads = ad_vehpro.main_ad
WHERE ads_cat = :ads_cat AND
ads.ad_status = :adStatus
ORDER BY date_renewed
DESC LIMIT 4
EDITED: I add the tables:
CREATE TABLE IF NOT EXISTS `ads` (
`id_ads` int(10) unsigned NOT NULL AUTO_INCREMENT,
`id_profiles_key` varchar(20) NOT NULL,
`id_shops` int(4) NOT NULL DEFAULT '1',
`ads_cat` int(2) NOT NULL COMMENT 'main category: vehicule, immobilier,...',
`ads_scat` int(3) NOT NULL COMMENT 'sous cat: voiture, moto,...',
`form_id` varchar(30) NOT NULL COMMENT 'form key',
`city_id` int(5) NOT NULL,
`district_id` int(5) NOT NULL,
`adtype_id` int(1) NOT NULL DEFAULT '1' COMMENT '1: offre, 2: demande',
`ads_title` varchar(200) NOT NULL,
`ads_description` longtext NOT NULL,
`ads_price` int(11) NOT NULL,
`num_img` int(2) NOT NULL DEFAULT '1' COMMENT 'number of images',
`num_vid` int(2) NOT NULL DEFAULT '0' COMMENT 'number of video',
`num_com` int(3) NOT NULL DEFAULT '0' COMMENT 'number of comments',
`to_pin` int(1) NOT NULL DEFAULT '0' COMMENT 'ad that will be pinned. 0: no, 1: yes',
`date_inserted` varchar(20) NOT NULL,
`date_modified` varchar(20) NOT NULL,
`date_renewed` varchar(20) NOT NULL,
`date_pinned` varchar(20) NOT NULL DEFAULT '0',
`ad_status` int(1) NOT NULL DEFAULT '1' COMMENT '0: not active, 1: active, 2: deleted, 3: pinned',
PRIMARY KEY (`id_ads`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ;
CREATE TABLE IF NOT EXISTS `ad_car` (
`id_ad` int(10) unsigned NOT NULL AUTO_INCREMENT,
`main_ad` int(5) NOT NULL COMMENT 'this will refer to main table ads (id_ads)',
`id_profiles` varchar(20) NOT NULL,
`city_id` int(5) NOT NULL,
`district_id` int(5) NOT NULL COMMENT 'district id from districts table',
`category_id` int(2) NOT NULL,
`make_id` int(5) NOT NULL,
`model_id` int(5) NOT NULL,
`model_year` int(4) NOT NULL,
`engine` int(2) NOT NULL,
`fuel` int(1) NOT NULL,
`mileage` bigint(7) NOT NULL,
`transmission` int(1) NOT NULL,
`wheed_drive` int(1) NOT NULL,
`in_color` varchar(7) NOT NULL,
`ex_color` varchar(7) NOT NULL,
`seats` int(2) NOT NULL,
`doors` int(1) NOT NULL,
`tax` varchar(5) NOT NULL,
`warranty` int(1) NOT NULL,
`hands` int(1) NOT NULL,
`security` longtext NOT NULL,
`comfort` longtext NOT NULL,
`aesthetic` longtext NOT NULL,
`adreference` varchar(10) NOT NULL,
`ad_price` bigint(20) NOT NULL,
`ad_priceneg` int(1) NOT NULL,
`when_inserted` varchar(20) NOT NULL,
`when_modified` varchar(20) NOT NULL,
`ad_status` int(1) NOT NULL DEFAULT '1' COMMENT '0: not active, 1: active, 2: deleted',
`not_listed` longtext NOT NULL,
PRIMARY KEY (`id_ad`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;
CREATE TABLE IF NOT EXISTS `ad_vehpro` (
`id_ad` int(10) unsigned NOT NULL AUTO_INCREMENT,
`main_ad` int(5) NOT NULL COMMENT 'this will refer to main table ads (id_ads)',
`id_profiles` varchar(20) NOT NULL,
`city_id` int(5) NOT NULL,
`district_id` int(5) NOT NULL COMMENT 'district id from districts table',
`category_id` int(2) NOT NULL,
`vehpro_type` int(1) NOT NULL,
`make_id` int(5) NOT NULL,
`model_id` int(5) NOT NULL,
`model_year` int(4) NOT NULL,
`engine` int(2) NOT NULL,
`fuel` int(1) NOT NULL,
`mileage` bigint(7) NOT NULL,
`transmission` int(1) NOT NULL,
`wheed_drive` int(1) NOT NULL,
`in_color` varchar(7) NOT NULL,
`ex_color` varchar(7) NOT NULL,
`seats` int(2) NOT NULL,
`doors` int(1) NOT NULL,
`tax` varchar(5) NOT NULL,
`warranty` int(1) NOT NULL,
`hands` int(1) NOT NULL,
`security` longtext NOT NULL,
`comfort` longtext NOT NULL,
`aesthetic` longtext NOT NULL,
`adreference` varchar(10) NOT NULL,
`ad_price` bigint(20) NOT NULL,
`ad_priceneg` int(1) NOT NULL,
`when_inserted` varchar(20) NOT NULL,
`when_modified` varchar(20) NOT NULL,
`ad_status` int(1) NOT NULL DEFAULT '1' COMMENT '0: not active, 1: active, 2: deleted',
`not_listed` longtext NOT NULL,
PRIMARY KEY (`id_ad`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
EDITED
I tried using LEFT JOIN but, it skips some fields:
$sqlAds = "SELECT * FROM `ads`"
. " LEFT JOIN ad_car ON ads.id_ads = ad_car.main_ad"
. " LEFT JOIN ad_vehpro ON ads.id_ads = ad_vehpro.main_ad"
. " WHERE ads_cat = :ads_cat AND ads.ad_status = :adStatus ORDER BY date_renewed DESC";
Thanks in advance

List the columns you explicitly want. Provide NULLvalues for the rest:
SELECT a.*, c.col1, c.col2
FROM `ads` a JOIN
ad_car c
ON a.id_ads = c.main_ad
WHERE ads_cat = :ads_cat AND
a.ad_status = :adStatus
UNION
SELECT a.*, v.col1, NULL as col2
FROM ads a JOIN
ad_vehpro v
ON a.id_ads = v.main_ad
WHERE ads_cat = :ads_cat AND
a.ad_status = :adStatus
ORDER BY date_renewed DESC
LIMIT 4;
Note: If you know there are no duplicates between the two subqueries, use UNION ALL rather than UNION. UNION incurs the overhead of removing duplicates.

Related

mysql query to fetch records from multiple tables and join

I have 5 tables named: schools, candidates, candidate_subjects, subjects, lgas
Each school belong to a lga, each candidate belong to a school, each candidate registers subjects
Below are the table structures:
CREATE TABLE `subjects` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(250) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
`code` varchar(10) DEFAULT NULL,
`exam_type_id` int(11) DEFAULT NULL,
`status` int(11) DEFAULT NULL,
`type` varchar(3) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=60 DEFAULT CHARSET=latin1;
CREATE TABLE `candidates` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`exam_no` varchar(20) DEFAULT NULL,
`surname` varchar(100) DEFAULT NULL,
`other_names` varchar(150) DEFAULT NULL,
`school_id` int(11) DEFAULT NULL,
`exam_type_id` int(11) DEFAULT NULL,
`dob` varchar(12) DEFAULT NULL,
`sex` varchar(6) DEFAULT NULL,
`no_of_subjects` int(2) DEFAULT NULL,
`nationality` varchar(20) DEFAULT NULL,
`state` varchar(20) DEFAULT NULL,
`lga` varchar(20) DEFAULT NULL,
`exam_year` varchar(4) DEFAULT NULL,
`date_created` varchar(255) DEFAULT NULL,
`date_modified` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
`registration_completed` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=28034 DEFAULT CHARSET=latin1;
CREATE TABLE `candidate_subjects` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`candidate_id` int(11) DEFAULT NULL,
`exam_type_id` int(10) DEFAULT NULL,
`subject_id` int(10) DEFAULT NULL,
`ca_score` int(11) DEFAULT NULL,
`exam_score` int(6) DEFAULT NULL,
`score_grade` varchar(10) DEFAULT NULL,
`date_created` varchar(10) DEFAULT NULL,
`date_modified` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=327740 DEFAULT CHARSET=latin1;
CREATE TABLE `schools` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`passcode` varchar(15) DEFAULT NULL,
`code` varchar(10) DEFAULT NULL,
`name` varchar(200) DEFAULT NULL,
`lga` int(11) DEFAULT NULL,
`address` varchar(250) DEFAULT NULL,
`phone` varchar(50) DEFAULT NULL,
`exam_year` varchar(10) DEFAULT NULL,
`eo_name` varchar(100) DEFAULT NULL,
`eo_phone` varchar(50) DEFAULT NULL,
`eo_email` varchar(100) DEFAULT NULL,
`date_created` varchar(10) DEFAULT NULL,
`date_modified` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
`profile_created` int(1) DEFAULT NULL,
`entries_purchased` int(11) DEFAULT NULL,
`entries_used` int(11) DEFAULT NULL,
`entries_remaining` int(11) DEFAULT NULL,
`scratchcard_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=652 DEFAULT CHARSET=latin1;
CREATE TABLE `lgas` (
`lga_id` int(11) NOT NULL AUTO_INCREMENT,
`lga_name` varchar(250) NOT NULL,
`state_id` varchar(20) NOT NULL,
PRIMARY KEY (`lga_id`)
) ENGINE=InnoDB AUTO_INCREMENT=786 DEFAULT CHARSET=latin1;
I want to generate a report for each lga like this:
S/No| Name of School |Eng|Mth|B.sc|....Total registered
That is name of school from the selected lga, total number of students from that school that registered for Eng, Mth, B.sc ... Total number of students that registered those subjects from that school
SELECT
b.name as school_name,
sum(case when e.name = 'Eng' then 1 else 0 end) as english_students,
sum(case when e.name = 'Mth' then 1 else 0 end) as math_students,
sum(case when e.name = 'B.sc' then 1 else 0 end) as whatever_this_is_students
FROM lgas a
LEFT JOIN schools b ON a.lga_id = b.lga
LEFT JOIN candidates c on b.id = c.school_id
LEFT JOIN candidate_subjects d on c.id = d.candidate_id
LEFT JOIN subjects e on d.subject_id = e.id
WHERE a.lda_id = 'selected_id'
GROUP by school_name;

MySQL find a row when the sum of points become bigger than number

I have such sql query
SELECT *,(p.datetime-u.createtime)/86400 as result
FROM tbl_user_points p
Inner join tbl_users u ON u.id=p.user_id
GROUP BY p.user_id
HAVING SUM(p.points) > 100
order by SUM(p.points)
i need to find the datetime( the row in table tbl_user_points), when each users reached.
For more information Here the schemata of table
tbl_user_points
CREATE TABLE `tbl_user_points` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned NOT NULL,
`action` int(10) unsigned NOT NULL,
`description` varchar(255) DEFAULT '',
`points` int(10) NOT NULL DEFAULT '0',
`datetime` int(10) unsigned NOT NULL,
`club_id` int(10) unsigned DEFAULT NULL,
`event_id` int(10) unsigned DEFAULT NULL,
`location_id` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='Achieved users points for any actions.';
Here the schemata of table
tbl_users
CREATE TABLE `tbl_users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`email` varchar(128) NOT NULL,
`activkey` varchar(128) NOT NULL DEFAULT '',
`createtime` int(11) NOT NULL,
`lastvisit` int(11) NOT NULL,
`superuser` int(1) NOT NULL DEFAULT '0',
`status` int(1) NOT NULL DEFAULT '1',
`first_name` varchar(128) DEFAULT NULL,
`last_name` varchar(128) DEFAULT NULL,
`gender` varchar(6) DEFAULT NULL,
`locale` varchar(45) DEFAULT NULL,
`service` varchar(45) NOT NULL,
`service_id` varchar(255) DEFAULT NULL,
`location` varchar(128) DEFAULT NULL,
`state` int(3) DEFAULT NULL,
`photo` varchar(255) DEFAULT NULL,
`city` varchar(125) DEFAULT NULL,
`about_me` varchar(255) DEFAULT NULL,
`user_code` varchar(10) DEFAULT NULL,
`loyalty_level` varchar(45) DEFAULT 'basic' COMMENT 'Level of loyalty for current user',
`updatetime` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
UNIQUE KEY `user_code_UNIQUE` (`user_code`),
KEY `status` (`status`),
KEY `superuser` (`superuser`)
) ENGINE=InnoDB AUTO_INCREMENT=1033 DEFAULT CHARSET=utf8;
sample input
tbl_user_points
id | user_id|action|description|points| datetime
2246 1 1 First visit 5 1383331212
2254 1 2 Second visit 15 1383354853
2255 1 3 Winner 25 1383360231
2256 2 1 First visit 5 1383331202
2257 2 2 Second visit 15 1383354553
2258 2 3 Winner 25 1383360211
tbl_user simple,for example
id=1,createtime=1313000000
id=2,createtime=1313000001
for HAVING SUM(p.points) > 15
output should be
user_id datetime
1 1383354853
2 1383354553
Use CASE syntax. Check this link:
http://dev.mysql.com/doc/refman/5.0/en/case.html.
You can achieve it by using statements like this:
Select X, case when y>100 then desired_row when y<100 then desired_row end as 'desired_row' from your_table where column=your_condition order by 1
Here you're conditioning the select clause by as many cases or conditions you requiere.

Mysql query failed after adding category table

When i run this query i'm keeping getting this error Database query failed 1054 - Unknown column 'cv.employeeIDFK' in 'on clause'
This only happen when I add the category in my query
FROM opjb_cv AS cv , opjb_cvCategory AS cv_cat
AND cv_cat.categoryIDFK IN ( 1,2,3,4,5,11,22,24,26,28 )
AND cv_cat.cvIDFK = cv.id
This is my query which is failing as you can see i have added all information but still its failing i cant seem to find anything wrong with this.
SELECT DISTINCT cv.id, cv.targetJobTitle, cv.targetJobTitleAlt, cv.recentEmployer, employee.firstName,
employee.surname, cv.recentJobTitle, cv.modifyAt, cv.city, cv.countryCountyFK, cv.countryStatesFK, cv.countryISO2FK, cv.experienceIDFK,
cv.careerIDFK, cv.areYouAuth, country.countryName, cv.employeeIDFK as user_id ,
match ( cv.title, cv.recentJobTitle, cv.targetJobTitle, cv.targetJobTitleAlt ) AGAINST ('desktop' IN BOOLEAN MODE) AS relevance
FROM opjb_cv AS cv , opjb_cvCategory AS cv_cat
JOIN opjb_employee AS employee ON cv.employeeIDFK = employee.id
JOIN opjb_country AS country ON cv.countryISO2FK=country.iso2
JOIN opjb_experience AS experience ON cv.experienceIDFK = experience.id
JOIN opjb_type AS type ON cv.jobTypeIDFK = type.id
JOIN opjb_education AS education ON cv.educationIDFK = education.id
JOIN opjb_countryStates as countryStates ON cv.countryStatesFK = countryStates.code
WHERE cv.showTo=1
AND cv.status=1
AND cv.countryISO2FK='GB'
AND match ( cv.title, cv.recentJobTitle, cv.targetJobTitle, cv.targetJobTitleAlt ) AGAINST ('desktop' IN BOOLEAN MODE )
AND cv_cat.categoryIDFK IN ( 1,2,3,4,5,11,22,24,26,28 )
AND cv_cat.cvIDFK = cv.id
AND experience.id=5
AND type.id=1
AND education.id=7
AND cv.modifyAt > NOW() - INTERVAL 3 DAY AND ( cv.salaryMin <= 48000 OR cv.salaryMax <= 48000 )
AND cv.countryStatesFK ='EG'
ORDER BY relevance DESC
These are all the tables which is involde in this query.
CREATE TABLE IF NOT EXISTS `opjb_country` (
`iso2` char(2) NOT NULL,
`iso3` char(3) NOT NULL,
`isoNo` smallint(3) NOT NULL,
`countryName` varchar(100) NOT NULL,
`regionIDFK` int(11) NOT NULL,
`isActive` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`iso2`),
KEY `regionIDFK` (`regionIDFK`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `opjb_countryStates`
--
CREATE TABLE IF NOT EXISTS `opjb_countryStates` (
`code` varchar(40) NOT NULL default '',
`name` varchar(100) default NULL,
`countryISO2FK` char(2) NOT NULL default 'US',
`isActive` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`code`,`countryISO2FK`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `opjb_cv`
--
CREATE TABLE IF NOT EXISTS `opjb_cv` (
`id` int(11) NOT NULL auto_increment,
`type` tinyint(1) NOT NULL default '0',
`fileName` varchar(100) NOT NULL,
`fileType` varchar(15) NOT NULL,
`fileExe` varchar(5) NOT NULL,
`fileSize` int(11) NOT NULL default '0',
`filePath` varchar(255) NOT NULL,
`originalName` varchar(100) NOT NULL,
`fileHash` varchar(40) NOT NULL,
`title` varchar(30) NOT NULL,
`description` varchar(255) NOT NULL,
`showTo` tinyint(1) NOT NULL default '0',
`defaultCV` tinyint(1) NOT NULL default '0',
`targetJobTitle` varchar(100) NOT NULL,
`targetJobTitleAlt` varchar(100) NOT NULL,
`educationIDFK` int(6) NOT NULL default '0',
`careerIDFK` int(6) NOT NULL default '0',
`city` varchar(100) NOT NULL,
`areYouAuth` varchar(100) NOT NULL,
`recentJobTitle` varchar(100) NOT NULL,
`recentEmployer` varchar(100) NOT NULL,
`recentIndustry` varchar(100) NOT NULL,
`recentCareer` int(6) NOT NULL default '0',
`recentStartDate` date NOT NULL,
`recentEndDate` varchar(50) NOT NULL,
`jobTypeIDFK` int(6) NOT NULL default '0',
`jobStatusIDFK` int(6) NOT NULL default '0',
`salaryMin` varchar(20) NOT NULL default '0',
`salaryMax` varchar(20) NOT NULL default '0',
`salaryCurrency` varchar(5) NOT NULL default 'GBP',
`salaryType` tinyint(2) NOT NULL default '5',
`relocate` tinyint(1) NOT NULL default '0',
`willing_to_travel` tinyint(2) NOT NULL default '0',
`availability` tinyint(1) NOT NULL default '0',
`startDate` varchar(30) NOT NULL,
`positions` varchar(100) NOT NULL,
`userComments` text,
`noViews` int(7) NOT NULL default '0',
`status` tinyint(1) NOT NULL default '0',
`adminComments` text,
`employeeIDFK` int(11) NOT NULL default '0',
`countryISO2FK` char(2) NOT NULL default 'US',
`countryStatesFK` varchar(100) NOT NULL,
`countryCountyFK` varchar(100) NOT NULL,
`experienceIDFK` int(6) NOT NULL default '0',
`modifyAt` datetime NOT NULL,
`createdAt` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `employeeIDFK` (`employeeIDFK`),
KEY `countryISO2FK` (`countryISO2FK`),
FULLTEXT KEY `searchCV` (`title`,`targetJobTitle`,`targetJobTitleAlt`,`recentJobTitle`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
-- --------------------------------------------------------
--
-- Table structure for table `opjb_cvCategory`
--
CREATE TABLE IF NOT EXISTS `opjb_cvCategory` (
`cvIDFK` int(11) NOT NULL default '0',
`categoryIDFK` int(11) NOT NULL default '0',
PRIMARY KEY (`cvIDFK`,`categoryIDFK`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `opjb_education`
--
CREATE TABLE IF NOT EXISTS `opjb_education` (
`id` int(6) NOT NULL auto_increment,
`educationName` varchar(100) NOT NULL,
`lang` varchar(50) NOT NULL default 'english',
`isActive` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ;
-- --------------------------------------------------------
--
-- Table structure for table `opjb_employee`
--
CREATE TABLE IF NOT EXISTS `opjb_employee` (
`id` int(11) NOT NULL auto_increment,
`emailAddress` varchar(100) NOT NULL,
`username` varchar(30) NOT NULL,
`passwd` varchar(40) NOT NULL,
`title` varchar(20) NOT NULL,
`firstName` varchar(100) NOT NULL,
`middleName` varchar(50) NOT NULL,
`surname` varchar(100) NOT NULL,
`address` varchar(150) NOT NULL,
`address2` varchar(100) NOT NULL,
`city` varchar(100) NOT NULL,
`countryCountyFK` varchar(100) NOT NULL,
`countryStatesFK` varchar(100) NOT NULL,
`countryISO2FK` char(2) NOT NULL default 'US',
`postCode` varchar(20) NOT NULL,
`careerStatus` tinyint(1) NOT NULL default '0',
`contPref` tinyint(1) NOT NULL default '0',
`webSite` varchar(100) NOT NULL,
`job_title` varchar(255) NOT NULL,
`recent_employer` varchar(255) NOT NULL,
`mobile_no` varchar(30) NOT NULL,
`home_no` varchar(30) NOT NULL,
`categoryIDFK` int(6) default NULL,
`careerDegreeIDFK` int(6) default NULL,
`educationIDFK` int(6) default NULL,
`experienceIDFK` int(6) default NULL,
`pers_statement` text,
`actKey` varchar(100) NOT NULL,
`comments` varchar(255) NOT NULL,
`status` tinyint(1) NOT NULL default '0',
`isActive` tinyint(1) NOT NULL default '0',
`lastVisit` datetime NOT NULL,
`modifyAt` datetime NOT NULL,
`createdAt` datetime NOT NULL,
`createip` varchar(20) NOT NULL default '0',
`loginip` varchar(20) NOT NULL default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `emailAddress` (`emailAddress`),
UNIQUE KEY `username` (`username`),
KEY `city` (`city`,`countryCountyFK`),
KEY `countryISO2FK` (`countryISO2FK`),
KEY `idx_fullname` (`firstName`,`surname`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
-- --------------------------------------------------------
--
-- Table structure for table `opjb_experience`
--
CREATE TABLE IF NOT EXISTS `opjb_experience` (
`id` int(6) NOT NULL auto_increment,
`experienceName` varchar(100) NOT NULL,
`lang` varchar(50) NOT NULL default 'english',
`isActive` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=8 ;
-- --------------------------------------------------------
--
-- Table structure for table `opjb_type`
--
CREATE TABLE IF NOT EXISTS `opjb_type` (
`id` int(6) NOT NULL auto_increment,
`typeName` varchar(100) NOT NULL,
`lang` varchar(50) NOT NULL default 'english',
`isActive` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;

n-number of nested inner join

I have a sql-statement which correctly fetches data from one table. However, I need to fetch in the same way from n number of tables named table_n. All of these tables contain a 3-field primary key of projid, docid and revnr. I need to return n as docType as well, to differentiate the tables. The result will be sorted by projid and/or docid.
I tried sorting all the outputs from the different queries in PHP but it was way too slow (at least a few seconds on a 3MB database). I'm convinced MySQL/MSSQL will do it faster.
This is my current query:
SELECT a.* FROM `table_1` a
INNER JOIN (SELECT docid,
Max(revnr) max_val
FROM `table_1`
WHERE ( projid = something )
GROUP BY docid) b
ON a.docid = b.docid
AND a.revnr = b.max_val ORDER BY docid DESC
My current query gets the rows with highest revnr for each docid and projid.
I'm developing on MySQL but I need it to work on MSSQL as well. A general SQL solution would be great.
Thanks!
EDIT: Table schemas of the tables i currently have:
CREATE TABLE IF NOT EXISTS `table_1` (
`projid` int(11) NOT NULL,
`docid` int(11) NOT NULL,
`revnr` int(11) NOT NULL,
`revname` varchar(64) NOT NULL,
`signedOn` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`sign` int(11) NOT NULL,
`ritningsnr` varchar(128) NOT NULL,
`moment` varchar(256) NOT NULL,
`omrade` varchar(256) NOT NULL,
`start` datetime NOT NULL,
`stop` datetime NOT NULL,
`extTodo` int(11) NOT NULL,
PRIMARY KEY (`projid`,`docid`,`revnr`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='egenkontroll';
CREATE TABLE IF NOT EXISTS `table_2` (
`projid` int(11) NOT NULL,
`docid` int(11) NOT NULL,
`revnr` int(11) NOT NULL,
`revname` varchar(64) NOT NULL,
`signedOn` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`sign` int(11) NOT NULL,
`extWater` int(11) NOT NULL,
`extRisk` int(11) NOT NULL,
`extSystem` int(11) NOT NULL,
`extHelp` int(11) NOT NULL,
`extProvtryck` int(11) NOT NULL,
`extDoc` int(11) NOT NULL,
`extEgenkontroll` int(11) NOT NULL COMMENT 'exttabell',
`extOther` int(11) NOT NULL,
`extMontorer` int(11) NOT NULL,
PRIMARY KEY (`projid`,`docid`,`revnr`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='arbetsberedning';
CREATE TABLE IF NOT EXISTS `table_3` (
`projid` int(11) NOT NULL,
`docid` int(11) NOT NULL,
`revnr` int(11) NOT NULL,
`revname` varchar(64) NOT NULL,
`adress` varchar(256) NOT NULL,
`pipesMark` tinyint(1) NOT NULL,
`pipesKulvert` tinyint(1) NOT NULL,
`pipesBasement` tinyint(1) NOT NULL,
`pipesVaning` tinyint(1) NOT NULL,
`pipesIngjutna` tinyint(1) NOT NULL,
`ledningTappvatten` tinyint(1) NOT NULL,
`ledningVarmevatten` tinyint(1) NOT NULL,
`ledningHetvatten` tinyint(1) NOT NULL,
`ledningKylaPrim` tinyint(1) NOT NULL,
`ledningKylaSek` tinyint(1) NOT NULL,
`ledningGas` tinyint(1) NOT NULL,
`ledningLuft` tinyint(1) NOT NULL,
`ledningAvlopp` tinyint(1) NOT NULL,
`ledningOther` varchar(512) NOT NULL,
`materialGjutjarn` tinyint(1) NOT NULL,
`materialSteel` tinyint(1) NOT NULL,
`materialKoppar` tinyint(1) NOT NULL,
`materialPlast` tinyint(1) NOT NULL,
`materialRostfritt` tinyint(1) NOT NULL,
`materialOther` varchar(512) NOT NULL,
`omfattningLength` int(11) NOT NULL COMMENT 'meter',
`omfattningDimension` varchar(16) NOT NULL,
`omfattningRitningnr` varchar(128) NOT NULL,
`doneWithPump` tinyint(1) NOT NULL,
`doneWithVattenledning` tinyint(1) NOT NULL,
`doneWithKompressor` tinyint(1) NOT NULL,
`doneWithTathetsprovare` tinyint(1) NOT NULL,
`tryckmedieVatten` tinyint(1) NOT NULL,
`tryckmedieLuft` tinyint(1) NOT NULL,
`tryckmedieOther` varchar(128) NOT NULL,
`manometerDiameter` int(11) NOT NULL COMMENT 'mm',
`manometerGradering` int(11) NOT NULL COMMENT 'kPa',
`manometerReadPressure` int(11) NOT NULL,
`manometerTid` int(11) NOT NULL COMMENT 'sekunder',
`testedOn` datetime NOT NULL,
`testedBy` varchar(128) NOT NULL COMMENT '"id_" + (userid)',
`comments` varchar(1024) NOT NULL,
`commentsBy` varchar(128) NOT NULL COMMENT '"id_" + (userid)',
`signedOn` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`sign` int(11) NOT NULL,
PRIMARY KEY (`projid`,`docid`,`revnr`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
The fields I need are projid, docid, revnr, revname, signedOn, sign and are present in all current and future tables.

Mysql Join / Union issue

I am trying to create a report that pulls data from 2 tables: a & b. The report is grouped by a.clock. Most of the data for the report comes from a - that part is working fine. a.clock links with b.userID.
The part i am struggling with is for one of the columns the data comes from b. I need to total up the following for each a.clock grouping in the main report (this query works standalone)
SELECT (
SUM(
TIME_TO_SEC(
TIMEDIFF(
CONCAT(b.endDate, ' ', b.outTime),
CONCAT(b.startDate, ' ', b.inTime)
)
) / 3600
)
) AS 'Misc Hours' FROM b
In other words, i need to total the Misc Hours (in b) for each a.clock. I thought maybe joining the b table was necessary but that didn't seem to work. Any suggestions?
Here are the table definitions (sorry, verbose)
CREATE TABLE `a` (
`laborID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`type` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '0=sched; 1=accepted; 2=complete; 3=authorize',
`laborType` varchar(15) NOT NULL DEFAULT '0' COMMENT 'Lookup',
`hours` varchar(15) NOT NULL DEFAULT '',
`wage` varchar(15) NOT NULL DEFAULT '',
`id` int(10) unsigned NOT NULL DEFAULT '0',
`laborDate` date NOT NULL,
`ot` varchar(15) NOT NULL,
`clock` varchar(15) NOT NULL,
`setup` varchar(15) NOT NULL DEFAULT '',
`ot2` varchar(15) NOT NULL,
`wageOT1` varchar(15) NOT NULL,
`wageOT2` varchar(15) NOT NULL,
`inTime` varchar(15) NOT NULL,
`outTime` varchar(15) NOT NULL,
`startDateString` varchar(125) NOT NULL,
`endDateString` varchar(125) NOT NULL,
`authRequestDate` datetime NOT NULL,
`authRequestUser` int(10) unsigned NOT NULL,
`authRequestReason` text NOT NULL,
`authDate` datetime NOT NULL,
`authUser` int(10) unsigned NOT NULL,
`authRequired` varchar(45) NOT NULL,
`km` varchar(45) NOT NULL,
`travelTime` varchar(45) NOT NULL,
`actualInTime` varchar(45) NOT NULL,
`actualOutTime` varchar(45) NOT NULL,
`actualKm` varchar(45) NOT NULL,
`actualTravelTime` varchar(45) NOT NULL,
`intNotes` text,
`extNotes` text,
`billableReason` text,
`billableHours` varchar(45) DEFAULT NULL,
`actualHours` varchar(45) DEFAULT NULL,
`overtime` varchar(45) DEFAULT NULL,
`followUpReason` text NOT NULL,
`responseType` varchar(45) DEFAULT NULL,
`followUpType` int(10) unsigned DEFAULT NULL,
`billableDrop` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`laborID`),
KEY `id` (`id`),
KEY `type` (`type`),
KEY `laborDate` (`laborDate`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;
CREATE TABLE `b` (
`timecodeID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`userID` int(10) unsigned NOT NULL,
`inTime` varchar(45) NOT NULL,
`outTime` varchar(45) NOT NULL,
`startDateString` varchar(145) NOT NULL,
`endDateString` varchar(145) NOT NULL,
`startDate` varchar(45) NOT NULL,
`endDate` varchar(45) NOT NULL,
`type` varchar(45) NOT NULL,
`comments` text NOT NULL,
`multiDay` tinyint(3) unsigned NOT NULL,
PRIMARY KEY (`timecodeID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Well if you have multiple rows in each of the table then you will get larger sum as each row in labor will join with each row in timecodes. So the idea is to have nested query group by clock and userid to get one row each as per the groupping
SELECT A.Clock, A.hours, B.'Misc Hours'
FROM
(
SELECT labor.clock,
SUM(hours) Hours
FROM labor
GROUP BY labor.clock
) A
INNER JOIN
(
SELECT timecodes.userID,
(SUM(
TIME_TO_SEC(
TIMEDIFF(
CONCAT(timecodes.endDate,' ',timecodes.outTime),
CONCAT(timecodes.startDate,' ',timecodes.inTime)
)
)/3600
)
) AS 'Misc Hours'
FROM timecodes
GROUP BY timecodes.userID
) AS B ON A.Clock = B.UserId
SELECT timecodes.userID,
(SUM(
TIME_TO_SEC(
TIMEDIFF(
CONCAT(timecodes.endDate,' ',timecodes.outTime),
CONCAT(timecodes.startDate,' ',timecodes.inTime)
)
)/3600
)
)
AS 'Misc Hours'
FROM timecodes WHERE timecodes.userID=labor.clock GROUP BY labor.clock