the union of two queries - php
Help to merge the two sql query (TECDOC).
Display the name and part number;
Display the details of technical parameters.
How to combine these two queries?
SELECT
ART_ARTICLE_NR,
SUP_BRAND,
DES_TEXTS.TEX_TEXT AS ART_COMPLETE_DES_TEXT,
DES_TEXTS2.TEX_TEXT AS ART_STATUS_TEXT
FROM ARTICLES
INNER JOIN DESIGNATIONS ON DESIGNATIONS.DES_ID = ART_COMPLETE_DES_ID
INNER JOIN DES_TEXTS ON DES_TEXTS.TEX_ID = DESIGNATIONS.DES_TEX_ID
INNER JOIN SUPPLIERS ON SUP_ID = ART_SUP_ID
INNER JOIN ART_COUNTRY_SPECIFICS ON ACS_ART_ID = ART_ID
INNER JOIN DESIGNATIONS
AS DESIGNATIONS2 ON DESIGNATIONS2.DES_ID = ACS_KV_STATUS_DES_ID
INNER JOIN DES_TEXTS
AS DES_TEXTS2 ON DES_TEXTS2.TEX_ID = DESIGNATIONS2.DES_TEX_ID
WHERE
ART_ID IN (
52277
) AND
DESIGNATIONS.DES_LNG_ID = 19 AND
DESIGNATIONS2.DES_LNG_ID = 19;
SELECT
DES_TEXTS.TEX_TEXT AS CRITERIA_DES_TEXT,
IFNULL(DES_TEXTS2.TEX_TEXT, ACR_VALUE) AS CRITERIA_VALUE_TEXT
FROM
ARTICLE_CRITERIA
LEFT JOIN DESIGNATIONS
AS DESIGNATIONS2 ON DESIGNATIONS2.DES_ID = ACR_KV_DES_ID
LEFT JOIN DES_TEXTS
AS DES_TEXTS2 ON DES_TEXTS2.TEX_ID = DESIGNATIONS2.DES_TEX_ID
LEFT JOIN CRITERIA ON CRI_ID = ACR_CRI_ID
LEFT JOIN DESIGNATIONS ON DESIGNATIONS.DES_ID = CRI_DES_ID
LEFT JOIN DES_TEXTS ON DES_TEXTS.TEX_ID = DESIGNATIONS.DES_TEX_ID
WHERE
ACR_ART_ID IN (
52277
) AND
(DESIGNATIONS.DES_LNG_ID IS NULL OR DESIGNATIONS.DES_LNG_ID = 19) AND
(DESIGNATIONS2.DES_LNG_ID IS NULL OR DESIGNATIONS2.DES_LNG_ID = 19);
CREATE TABLE IF NOT EXISTS articles ( ART_ID int(11) NOT NULL, ART_ARTICLE_NR varchar(66) NOT NULL, ART_SUP_ID smallint(6) DEFAULT NULL, ART_DES_ID int(11) DEFAULT NULL, ART_COMPLETE_DES_ID int(11) DEFAULT NULL, ART_PACK_SELFSERVICE smallint(6) DEFAULT NULL, ART_MATERIAL_MARK smallint(6) DEFAULT NULL, ART_REPLACEMENT smallint(6) DEFAULT NULL, ART_ACCESSORY smallint(6) DEFAULT NULL, ART_BATCH_SIZE1 int(11) DEFAULT NULL, ART_BATCH_SIZE2 int(11) DEFAULT NULL, PRIMARY KEY (ART_ID), KEY ART_ARTICLE_NR (ART_ARTICLE_NR(10)) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS article_criteria ( ACR_ART_ID int(11) NOT NULL, ACR_GA_ID int(11) NOT NULL, ACR_SORT smallint(6) NOT NULL, ACR_CRI_ID smallint(6) NOT NULL, ACR_VALUE varchar(60) DEFAULT NULL, ACR_KV_DES_ID int(11) DEFAULT NULL, ACR_DISPLAY smallint(6) DEFAULT NULL, PRIMARY KEY (ACR_ART_ID,ACR_GA_ID,ACR_SORT) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS art_country_specifics ( ACS_ART_ID int(11) NOT NULL, ACS_PACK_UNIT int(11) DEFAULT NULL, ACS_QUANTITY_PER_UNIT int(11) DEFAULT NULL, ACS_KV_STATUS_DES_ID int(11) DEFAULT NULL, ACS_KV_STATUS varchar(9) DEFAULT NULL, ACS_STATUS_DATE datetime DEFAULT NULL, KEY ACS_ART_ID (ACS_ART_ID) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS criteria ( CRI_ID smallint(6) NOT NULL, CRI_DES_ID int(11) NOT NULL, CRI_SHORT_DES_ID int(11) DEFAULT NULL, CRI_UNIT_DES_ID int(11) DEFAULT NULL, CRI_TYPE binary(1) NOT NULL, CRI_KT_ID smallint(6) DEFAULT NULL, CRI_IS_INTERVAL smallint(6) DEFAULT NULL, CRI_SUCCESSOR smallint(6) DEFAULT NULL, PRIMARY KEY (CRI_ID) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS designations ( DES_ID int(11) NOT NULL, DES_LNG_ID smallint(6) NOT NULL, DES_TEX_ID int(11) NOT NULL, PRIMARY KEY (DES_ID,DES_LNG_ID) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS des_texts ( TEX_ID int(11) NOT NULL, TEX_TEXT text, PRIMARY KEY (TEX_ID) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS suppliers ( SUP_ID smallint(6) NOT NULL, SUP_BRAND varchar(60) DEFAULT NULL, SUP_SUPPLIER_NR smallint(6) DEFAULT NULL, SUP_COU_ID smallint(6) DEFAULT NULL, SUP_IS_HESS smallint(6) DEFAULT NULL, PRIMARY KEY (SUP_ID) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I think this might work. Please note that this is not tested (especially as you've neglected to provide us with the layout of your tables), and I've had to make guesses as to how articles is supposed to be correlated to article_criteria.
SELECT Articles.art_article_nr, Suppliers.sup_brand
Article_Designations.text, Country_Specific_Designations.text,
Article_Criteria_Designations.value,
Article_Criteria_Designations.text
FROM Articles
JOIN (SELECT Designations.des_id, Des_Texts.tex_text as text
FROM Designations
JOIN Des_Texts
ON Des_Texts.tex_id = Designations.des_tex_id
AND Designations.des_lng_id = 19) as Article_Designations
ON Article_Designations.des_id = Articles.art_complete_des_id
JOIN Suppliers
ON Suppliers.sup_id = Articles.art_sup_id
JOIN Art_Country_Specific
ON Art_Country_Specific.acs_art_id = Articles.art_id
JOIN (SELECT Designations.des_id, Des_Texts.tex_text as text
FROM Designations
JOIN Des_Texts
ON Des_Texts.tex_id = Designations.des_tex_id
AND Designations.des_lng_id = 19) as Country_Specific_Designations
ON Country_Specific_Designations.des_id = Art_Country_Specific.acs_kv_status_des_id
LEFT JOIN (SELECT Article_Criteria.acr_art_id,
COALESCE(Art_Cri_Designations.text, Article_Criteria.acr_value) as value,
Criteria_Designations.text
FROM Article_Criteria
LEFT JOIN (SELECT Designations.des_id, Des_Texts.tex_text as text
FROM Designations
JOIN Des_Texts
ON Des_Texts.tex_id = Designations.des_tex_id
AND Designations.des_lng_id = 19) as Art_Cri_Designations
ON Art_Cri_Designations.des_id = Article_Criteria.acr_kv_des_id
LEFT JOIN (SELECT Criteria.cri_id, Des_Texts.tex_text as text
FROM Criteria
JOIN Designations
ON Designations.des_id = Criteria.cri_des_id
JOIN Des_Texts
ON Des_Texts.tex_id = Designations.des_tex_id
AND Designations.des_lng_id = 19) as Criteria_Designations
ON Criteria_Designations.cri_id = Article_Criteria.acr_cri_id
) as Article_Criteria_Designations
ON Article_Criteria_Designations.acr_art_id = Articles.art_id
WHERE Articles.art_id IN (52277)
Related
mySql combine two SELECT queries with JOIN
I have two mySql queries to get result from databases. I am trying to join them together. Query 1: SELECT userEwallets.id as ewalletId, users.id as userId , money_repositories.money as money, a.nestedUserId FROM userEwallets JOIN users ON users.id = userEwallets.userId JOIN money_repositories ON userEwallets.id = money_repositories.ewalletId WHERE ewalletNumber = 'SHIRR937303656' Query 2: SELECT nested.id as nestedUserId FROM userEwallets as nested JOIN users ON users.id = nested.userId JOIN money_repositories ON nested.id = money_repositories.ewalletId WHERE ewalletNumber = 'SHIRR9122331743' and then my combination command: SELECT userEwallets.id as ewalletId, users.id as userId , money_repositories.money as money, a.nestedUserId FROM ( SELECT nested.id as nestedUserId FROM userEwallets as nested JOIN users ON users.id = nested.userId JOIN money_repositories ON nested.id = money_repositories.ewalletId WHERE ewalletNumber = 'SHIRR912233' ) as a JOIN users ON users.id = userEwallets.userId JOIN money_repositories ON userEwallets.id = money_repositories.ewalletId WHERE ewalletNumber = 'SHIRR93730' I get this error: #1054 - Unknown column 'userEwallets.id' in 'field list' Both of commands are same but they have simple difference as ewalletNumber in where clause UPDATE WITH DATABASE STRUCTURE money_repositories table: CREATE TABLE IF NOT EXISTS `money_repositories` ( `id` int(11) NOT NULL AUTO_INCREMENT, `userId` int(11) NOT NULL, `ewalletId` int(11) NOT NULL, `money` int(11) NOT NULL, `createdAt` int(11) NOT NULL, `updatedAt` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_persian_ci AUTO_INCREMENT=4 ; userEwallets table: CREATE TABLE IF NOT EXISTS `userEwallets` ( `id` int(11) NOT NULL AUTO_INCREMENT, `userId` int(11) NOT NULL, `ewalletNumber` varchar(15) COLLATE utf8_persian_ci NOT NULL, `currencySymbol` varchar(5) COLLATE utf8_persian_ci NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `updatedAt` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_persian_ci AUTO_INCREMENT=7 ; users table: CREATE TABLE IF NOT EXISTS `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(20) COLLATE utf8_persian_ci NOT NULL, `password` varchar(65) COLLATE utf8_persian_ci NOT NULL, `name` varchar(20) COLLATE utf8_persian_ci NOT NULL, `family` varchar(20) COLLATE utf8_persian_ci NOT NULL, `birthDay` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, `email` varchar(20) COLLATE utf8_persian_ci NOT NULL, `mobileNumber` varchar(15) COLLATE utf8_persian_ci NOT NULL, `verifyCode` varchar(5) COLLATE utf8_persian_ci NOT NULL, `photoUri` varchar(50) COLLATE utf8_persian_ci NOT NULL, `ebanNumber` varchar(20) COLLATE utf8_persian_ci NOT NULL, `status` tinyint(1) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `updatedAt` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_persian_ci AUTO_INCREMENT=35 ;
userEwallets.id should be a.id in Select of your combination command. Because you are getting subquery as a. Modified combined query; SELECT a.id AS ewalletId, users.id AS userId, money_repositories.money AS money, a.nesteduserid FROM (SELECT nested.id AS nestedUserId, nested.id, nested.ewalletnumber FROM userewallets AS nested JOIN users ON users.id = nested.userid JOIN money_repositories ON nested.id = money_repositories.ewalletid WHERE nested.ewalletnumber = 'SHIRR912233') AS a JOIN users ON users.id = userewallets.userid JOIN money_repositories ON userewallets.id = money_repositories.ewalletid WHERE a.ewalletnumber = 'SHIRR93730' camleCase query fixed: SELECT a.id AS ewalletId, users.id AS userId, money_repositories.money AS money, a.nestedUserId FROM (SELECT nested.id AS nestedUserId, nested.id, nested.ewalletNumber FROM userEwallets AS nested JOIN users ON users.id = nested.userId JOIN money_repositories ON nested.id = money_repositories.ewalletId WHERE nested.ewalletNumber = 'SHIRR912233') AS a JOIN users ON users.id = nested.userId JOIN money_repositories ON userEwallets.id = money_repositories.ewalletId WHERE a.ewalletNumber = 'SHIRR937303'
Because you are not including table userEwallets in the query except in the sub query which won't be recognized outside the subquery. Try UPDATE Select users.id as userId, userEwallets.id As ewalletId,money_repositories.money From users Inner Join userEwallets ON userEwallets.userId= users.id Inner Join money_repositories ON money_repositories.userId=users.id And money_repositories.ewalletId = userEwallets.id Where userEwallets.ewalletNumber = 'SHIRR93730'
MySQL Select rows where the user has not voted yet (contest app)
I have a photo contest app where users can vote. I would like to select all of the contests where the logged in user has not voted yet. So I have two tables. The "contest" table : CREATE TABLE `contest` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL, `category_id` int(11) NOT NULL, `title` varchar(255) NOT NULL, `desc` text NOT NULL, `created_date` datetime NOT NULL, `started_date` datetime NOT NULL, `nb_user_min` int(11) NOT NULL, `nb_photo_max` int(11) NOT NULL, `nb_photo_per_user` int(11) NOT NULL, `duration` int(11) DEFAULT NULL, `status` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; The "contest_vote" table : CREATE TABLE `contest_vote` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `pic_id` int(11) DEFAULT NULL, `contest_id` int(11) DEFAULT NULL, `user_id` int(11) DEFAULT NULL, `date` datetime DEFAULT NULL, `ip` varchar(100) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; So to be clear, I want to get the number (or the list) of contests where the user has not voted yet. So I have tried with a LEFT JOIN but it doesn't return the good set of result. Here it the query I have until now : SELECT DISTINCT c.id, c.title, cv.user_id FROM contest c LEFT JOIN contest_vote cv ON cv.contest_id = c.id AND cv.user_id != ? GROUP BY contest_id ("?" represents the user_id parameter). Can you help me to solve this?
This is pretty simple do with a subquery. Just grab all contest without where user is voted like this: SELECT DISTINCT c.id, c.title FROM contest c WHERE c.id NOT IN (SELECT DISTINCT cv.contest_id FROM contest_vote cv WHERE cv.user_id = ?)
Try this one : SELECT DISTINCT c.id, c.title, cv.user_id FROM contest c LEFT JOIN contest_vote cv ON cv.contest_id = c.id AND cv.user_id != ? WHERE c.user_id = ? GROUP BY contest_id
i want to use left and inner join in 3 tables in mysql?
these are my tables. first one is appusers table. CREATE TABLE IF NOT EXISTS `appusers` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `email` varchar(50) NOT NULL, `is_active` tinyint(2) NOT NULL DEFAULT '0', `zip` varchar(20) NOT NULL, `city` text NOT NULL, `country` text NOT NULL, `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=23 ; second table is stickeruses table. CREATE TABLE IF NOT EXISTS `stickeruses` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL, `sticker_id` int(11) NOT NULL, `count` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=24 ; Third table is Devices CREATE TABLE IF NOT EXISTS `devices` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL, `regid` varchar(300) NOT NULL, `imei` varchar(50) NOT NULL, `device_type` tinyint(2) NOT NULL, `notification` tinyint(2) NOT NULL DEFAULT '1', `is_active` tinyint(2) NOT NULL DEFAULT '0', `activationcode` int(6) NOT NULL, `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=28 ; I Want to find the Sum(stickeruses.count) and COUNT(devices.id) for all appusers. Here is my query. SELECT `Appuser`.`id`, `Appuser`.`email`, `Appuser`.`country`, `Appuser`.`created`, `Appuser`.`is_active`, SUM(`Stickeruse`.`count`) AS total, COUNT(`Device`.`id`) AS tdevice FROM `stickerapp`.`appusers` AS `Appuser` LEFT JOIN `stickerapp`.`stickeruses` AS `Stickeruse` ON (`Stickeruse`.`user_id`=`Appuser`.`id`) INNER JOIN `stickerapp`.`devices` AS `Device` ON (`Device`.`user_id`=`Appuser`.`id`) WHERE `Appuser`.`is_active` = 1 GROUP BY `Appuser`.`id` LIMIT 10 When I am applying each join separately the results are right, but I want to combine both joins. And when I am doing it then results are wrong. please help.
When mixing JOIN and LEFT JOIN it is a good idea to use parentheses to make it clear what your intent is. I don't know what you need, but these syntaxes might give you different results: FROM a LEFT JOIN ( b JOIN c ON b..c.. ) bc ON a..bc.. FROM ( a LEFT JOIN b ON a..b.. ) ab JOIN c ON ab..c.. Also, you can rearrange them do FROM a JOIN c LEFT JOIN b (plus parentheses) or any of several other arrangements. Granted, some pairs rearrangements are equivalent. Also, beware; aggregates (such as SUM()) get inflated values when JOINing. Think of it this way: first the JOINs get all appropriate combinations of rows from the tables, then the SUM adds them up. With that in mind, see if this works better: SELECT a.`id`, a.`email`, a.`country`, a.`created`, a.`is_active`, ( SELECT SUM(`count`) FROM stickerapp.stickeruses WHERE user_id = a.id ) AS total, ( SELECT COUNT(*) FROM stickerapp.devices WHERE user_id = a.id ) AS tdevice FROM stickerapp.`appusers` AS a WHERE a.`is_active` = 1 GROUP BY a.`id` LIMIT 10
Improve speed of MySQL query [closed]
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center. Closed 10 years ago. EDIT: I reworked the query as follows: SELECT a.title, count(*),at.search_code FROM `qitz3_attributes_type` at left join qitz3_attributes a on a.attribute_type_id = at.id left join qitz3_attributes_property ap on ap.attribute_id = a.id left join qitz3_helloworld h on h.id = ap.property_id where at.id in (1,2,8,9,11) and a.search_filter = 1 and h.area=506 and h.expiry_date >= '2013-02-20 13:28:04' group by a.title order by search_code This seems much faster but I am still getting a using temporary and using filesort on the explain... id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE at range PRIMARY PRIMARY 4 NULL 5 Using where; Using temporary; Using filesort 1 SIMPLE a ref PRIMARY,Attribute type ID,Search filter,Attribute ... Attribute type ID 4 password.at.id 6 Using where 1 SIMPLE ap ref Property ID,Attribute ID,Attribute Property Attribute Property 4 password.a.id 142 Using where; Using index 1 SIMPLE h eq_ref PRIMARY,Area indexes,Expiry date PRIMARY 4 password.ap.property_id 1 Using where ENDEDIT I am working on a search component for a site I am developing and while it is all working there are a couple of queries that I would like to see running a touch faster. In order to populate a set of search filters (display the count of the number of properties that have each facility or are of a particular type) I am using the following two queries. The first will get a list of IDs that I then plug into the second query as follows: Based on the following info can anyone suggest a more efficient way to do this? I would really like to speed the first query up as it seems a little slow compared to the others. Is 150ms actually that slow? 15ms would be better... Thanks, Adam Query 1 (takes around 150ms): SELECT h.id, h.parent_id, h.level, h.title as property_title, h.area, h.region, h.department, h.city, LEFT(h.description, 250) as description, h.thumbnail, h.occupancy, h.swimming, g.path, (single_bedrooms + double_bedrooms + triple_bedrooms + quad_bedrooms + twin_bedrooms) as bedrooms, c.title as location_title, ( select min(tariff) from qitz3_tariffs where id = h.id ) as price, e.title as tariff_based_on, f.title as base_currency, a.title as property_type, a2.title as accommodation_type, ( select count(*) from qitz3_reviews where property_id = h.id group by h.id ) as reviews FROM qitz3_classifications c LEFT JOIN qitz3_helloworld h on c.id = h.area LEFT JOIN qitz3_attributes_property ap ON ap.property_id = h.id LEFT JOIN qitz3_attributes_type at ON at.id = ap.attribute_id LEFT JOIN qitz3_attributes a ON a.id = ap.attribute_id LEFT JOIN qitz3_attributes_property ap2 ON ap2.property_id = h.id LEFT JOIN qitz3_attributes_type at2 ON at2.id = ap2.attribute_id LEFT JOIN qitz3_attributes a2 ON a2.id = ap2.attribute_id LEFT JOIN qitz3_attributes e ON e.id = h.tariff_based_on LEFT JOIN qitz3_attributes f ON f.id = h.base_currency LEFT JOIN qitz3_classifications g ON g.id = h.city WHERE a.attribute_type_id = 1 AND a2.attribute_type_id = 2 AND c.id = 506 AND h.expiry_date >= '2013-02-20 12:05:13' AND h.id > 1 Explain: id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY c const PRIMARY PRIMARY 4 const 1 1 PRIMARY h ref PRIMARY,Area indexes,Expiry date Area indexes 4 const 615 Using where 1 PRIMARY ap ref Property ID,Attribute ID Property ID 4 password.h.id 21 Using where 1 PRIMARY at eq_ref PRIMARY PRIMARY 4 password.ap.attribute_id 1 Using index 1 PRIMARY a eq_ref PRIMARY,Attribute type ID PRIMARY 4 password.ap.attribute_id 1 Using where 1 PRIMARY ap2 ref Property ID,Attribute ID Property ID 4 password.ap.property_id 21 Using where 1 PRIMARY at2 eq_ref PRIMARY PRIMARY 4 password.ap2.attribute_id 1 Using index 1 PRIMARY a2 eq_ref PRIMARY,Attribute type ID PRIMARY 4 password.ap2.attribute_id 1 Using where 1 PRIMARY e eq_ref PRIMARY PRIMARY 4 password.h.tariff_based_on 1 1 PRIMARY f eq_ref PRIMARY PRIMARY 4 password.h.base_currency 1 1 PRIMARY g eq_ref PRIMARY PRIMARY 4 password.h.city 1 3 DEPENDENT SUBQUERY qitz3_reviews ref Property ID Property ID 4 password.h.id 1 Using index; Using temporary; Using filesort 2 DEPENDENT SUBQUERY qitz3_tariffs ref Property ID Property ID 4 password.h.id 2 Query 2 (takes around 30ms): SELECT a.id,count(attribute_id) as count, a.title AS attribute, a.published, at.title as facility_type, at.search_code FROM qitz3_attributes AS a LEFT JOIN qitz3_attributes_type at on at.id = a.attribute_type_id LEFT JOIN qitz3_attributes_property ap on ap.attribute_id = a.id WHERE search_filter = 1 AND a.published = 1 AND property_id in (152843,103180,152845,4628,5653,3865,107553,155945,106029,107575,149052,837,104264,98635,98636,98637,98638,3667,106838,3672,157278,155743,157791,157792,151153,151155,100725,106109,157569,157576,107145,150666,103310,5780,3480,102041,154016,3490,154018,932,153518,151991,154041,154042,4288,5832,149451,157646,102094,148444,153822,157407,153839,151536,157393,157395,157428,157429,102236,104770,157378,157380,157381,157382,157383,157654,104768,103746,153683,150175,4618,101050,104942,157229,157230,98515,104771,104944,3612,148721,104212,5307,3432,156676,102706,404,5518,156359,5252,102697,5271,98979,101827,149524,102676,107551,5685,101736,156538,152703,4730,151881,95838,3759,149769,5269,98429,153729,5233,703,5579,98943,157433,3157,155661,107347,147545,147547,5216,106345,156533,93833,158091,96403,3491,968,158195,158196,157580,104148,3030,94686,154725,150582,103027,99062,102462,4384,5634,153874,157974,101669,47,105285,102481,102234,5749,156793,153748,96404,151467,154292,147645,97471,100551,102090,4841,3563,155643,4656,98424,157243,150601,157415,4701,102283,100719,100738,5643,98425,98972,103261,531,3105,98108,150592,5719,150616,157532,3974,3212,157581,97469,97470,149183,157638,149730,102114,156395,153621,102560,102913,94684,5609,157578,98423,98971,102151,146734,150585,104287,155296,104956,94592,102433,147575,156325,106344,101766,107058,106560,103026,157848,98973,4303,5620,149767,150563,4407,104268,97876,156784,156786,149922,701,154317,153821,102480,348,102778,102779,102780,102781,102479,352,103025,98677,5254,98697,3995,156322,100305,98532,3833,5374,150172,151435,102368,102380,157228,103171,147740,152870,103579,3870,104037,103016,4995,105104,157605,5811,955,147643,156648,107802,101502,94685,3569,148755,150293,4122,157013,157297,98676,156794,102848,157635,157640,95717,98980,102764,102777,102782,36,101765,154373,149829,154955,107683,158176,102557,157552,103163,5760,104627,153561,266,151335,151176,147620,147379,3085,155760,106339,151424,106759,5145,104990,97877,155495,5241,156407,156625,3236,152782,96066,147617,3860,4614,3497,147883,158207,102985,104622,101816,157275,149037,4792,149226,3496,101825,102538,150571,105015,97874,157391,158192,102562,155032,5383,102558,104194,156740,101446,147615,5815,107081,155992,97473,148817,945,101751,158074,4249,101792,4532,152828,104316,157319,156071,157508,157510,148836,4745,153823,157942,3859,157442,100017,102555,147629,149272,157845,151256,101481,154735,154737,157652,106232,97991,4660,3309,157597,407,157658,154152,157374,153385,148037,158214,100452) GROUP BY a.id This query gives a count of the number of properties with each attribute (e.g. Golf, Air conditioning, property type etc). The good thing about this is that only attributes are shown that have properties. So as the user drills down attributes with no properties are not shown. This is basically down to the first query where I get a list of the properties matching a particular set of attributes. The tables are as follows: -- -- Table structure for table qitz3_attributes CREATE TABLE IF NOT EXISTS `qitz3_attributes` ( `id` int(11) NOT NULL AUTO_INCREMENT, `attribute_type_id` int(11) NOT NULL, `title` varchar(75) NOT NULL, `ordering` int(11) NOT NULL, `state` tinyint(4) NOT NULL DEFAULT '1', `published` int(11) NOT NULL, `search_filter` bit(1) NOT NULL, `language_code` varchar(6) NOT NULL DEFAULT 'en-GB', PRIMARY KEY (`id`), KEY `Attribute type ID` (`attribute_type_id`), KEY `Search filter` (`search_filter`), KEY `Published` (`published`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1522 ; -- -- Table structure for table qitz3_attributes_property CREATE TABLE IF NOT EXISTS `qitz3_attributes_property` ( `id` int(11) NOT NULL AUTO_INCREMENT, `property_id` int(11) NOT NULL, `attribute_id` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `Property ID` (`property_id`), KEY `Attribute ID` (`attribute_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=66261 ; -- -- Table structure for table qitz3_attributes_type CREATE TABLE IF NOT EXISTS `qitz3_attributes_type` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(75) NOT NULL, `language_code` varchar(6) NOT NULL, `field_name` varchar(25) NOT NULL, `search_code` varchar(25) NOT NULL, `state` int(11) NOT NULL DEFAULT '1', `published` int(11) NOT NULL DEFAULT '1', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=34 ; -- -- Table structure for table qitz3_classifications CREATE TABLE IF NOT EXISTS `qitz3_classifications` ( `id` int(11) NOT NULL AUTO_INCREMENT, `parent_id` int(10) unsigned NOT NULL DEFAULT '0', `lft` int(11) NOT NULL DEFAULT '0', `rgt` int(11) NOT NULL DEFAULT '0', `level` int(10) unsigned NOT NULL DEFAULT '0', `title` varchar(255) NOT NULL, `description` text NOT NULL, `path` varchar(255) NOT NULL DEFAULT '', `alias` varchar(255) NOT NULL, `access` tinyint(3) unsigned NOT NULL DEFAULT '0', `published` int(11) NOT NULL, `longitude` float(10,6) NOT NULL, `latitude` float(10,6) NOT NULL, PRIMARY KEY (`id`), KEY `idx_left_right` (`lft`,`rgt`), KEY `Alias index` (`alias`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=158052 ; -- -- Table structure for table qitz3_helloworld (Property table) CREATE TABLE IF NOT EXISTS `qitz3_helloworld` ( `id` int(11) NOT NULL AUTO_INCREMENT, `parent_id` int(10) NOT NULL DEFAULT '0', `lft` int(11) NOT NULL DEFAULT '0', `rgt` int(11) NOT NULL DEFAULT '0', `level` int(10) unsigned NOT NULL, `alias` varchar(250) NOT NULL DEFAULT '', `access` tinyint(3) unsigned NOT NULL DEFAULT '0', `path` varchar(255) NOT NULL DEFAULT '', `title` varchar(120) NOT NULL, `area` int(11) NOT NULL DEFAULT '0', `region` int(11) NOT NULL DEFAULT '0', `department` int(11) NOT NULL DEFAULT '0', `city` int(11) NOT NULL DEFAULT '0', `params` text NOT NULL, `created_by` int(10) NOT NULL DEFAULT '0', `created_on` datetime NOT NULL, `modified` datetime DEFAULT NULL, `expiry_date` date DEFAULT NULL, `availability_last_updated_on` datetime DEFAULT NULL, `modified_by` int(11) DEFAULT NULL, `lang` varchar(5) NOT NULL DEFAULT 'en-GB', `description` mediumtext NOT NULL COMMENT 'The summary and description for this accommodation', `internal_facilities_other` varchar(1000) NOT NULL, `external_facilities_other` varchar(1000) NOT NULL, `activities_other` varchar(5000) NOT NULL, `location_details` varchar(5000) NOT NULL, `getting_there` varchar(5000) NOT NULL, `thumbnail` varchar(150) NOT NULL, `occupancy` int(11) DEFAULT NULL, `single_bedrooms` int(11) NOT NULL, `double_bedrooms` int(11) NOT NULL, `triple_bedrooms` int(11) DEFAULT NULL, `quad_bedrooms` int(11) DEFAULT NULL, `twin_bedrooms` int(11) DEFAULT NULL, `childrens_beds` int(11) DEFAULT NULL, `cots` int(11) DEFAULT NULL, `extra_beds` int(11) DEFAULT NULL, `bathrooms` int(11) NOT NULL, `toilets` int(11) DEFAULT NULL, `swimming` int(11) NOT NULL, `latitude` decimal(10,7) DEFAULT NULL, `longitude` decimal(10,7) DEFAULT NULL, `nearest_town` varchar(50) DEFAULT NULL, `distance_to_coast` int(11) DEFAULT NULL, `additional_price_notes` varchar(3000) DEFAULT NULL, `base_currency` int(11) DEFAULT NULL, `tariff_based_on` int(11) DEFAULT NULL, `linen_costs` varchar(250) DEFAULT NULL, `changeover_day` int(11) DEFAULT NULL, `published` tinyint(4) NOT NULL DEFAULT '0', `video` tinyint(4) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), KEY `idx_left_right` (`lft`,`rgt`), KEY `Area indexes` (`area`,`region`,`department`), KEY `Expiry date` (`expiry_date`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=158249 ; -- -- Table structure for table qitz3_reviews CREATE TABLE IF NOT EXISTS `qitz3_reviews` ( `id` int(11) NOT NULL AUTO_INCREMENT, `property_id` int(11) NOT NULL, `title` varchar(150) NOT NULL, `review_text` varchar(4000) NOT NULL, `date` date NOT NULL, `rating` int(11) NOT NULL, `guest_name` varchar(75) NOT NULL, `guest_email` varchar(150) NOT NULL, `state` tinyint(3) NOT NULL DEFAULT '0', `published` tinyint(1) NOT NULL DEFAULT '0', `created` datetime NOT NULL, `created_by` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `Property ID` (`property_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=921 ; -- -- Table structure for table qitz3_tariffs CREATE TABLE IF NOT EXISTS `qitz3_tariffs` ( `tariff_id` int(11) NOT NULL AUTO_INCREMENT, `id` int(11) NOT NULL COMMENT 'Denotes the property listing ID', `start_date` date NOT NULL, `end_date` date NOT NULL, `tariff` int(11) NOT NULL COMMENT 'Price per booking period between the dates specified. dated spec', PRIMARY KEY (`tariff_id`), KEY `Property ID` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=9267 ;
Quick play, but trying to move the subselects out from the field list. SELECT h.id, h.parent_id, h.level, h.title as property_title, h.area, h.region, h.department, h.city, LEFT(h.description, 250) as description, h.thumbnail, h.occupancy, h.swimming, g.path, (single_bedrooms + double_bedrooms + triple_bedrooms + quad_bedrooms + twin_bedrooms) as bedrooms, c.title as location_title, Sub1.price, e.title as tariff_based_on, f.title as base_currency, a.title as property_type, a2.title as accommodation_type, Sub2.reviews FROM qitz3_classifications c LEFT JOIN qitz3_helloworld h on c.id = h.area LEFT JOIN qitz3_attributes_property ap ON ap.property_id = h.id LEFT JOIN qitz3_attributes_type at ON at.id = ap.attribute_id LEFT JOIN qitz3_attributes a ON a.id = ap.attribute_id LEFT JOIN qitz3_attributes_property ap2 ON ap2.property_id = h.id LEFT JOIN qitz3_attributes_type at2 ON at2.id = ap2.attribute_id LEFT JOIN qitz3_attributes a2 ON a2.id = ap2.attribute_id LEFT JOIN qitz3_attributes e ON e.id = h.tariff_based_on LEFT JOIN qitz3_attributes f ON f.id = h.base_currency LEFT JOIN qitz3_classifications g ON g.id = h.city LEFT JOIN ( SELECT id, MIN(tariff) AS price FROM qitz3_tariffs GROUP BY id) Sub1 ON Sub1.Id = h.id LEFT JOIN ( SELECT property_id, COUNT(*) AS reviews FROM qitz3_reviews GROUP BY property_id ) as Sub2 ON Sub2.property_id = h.id WHERE a.attribute_type_id = 1 AND a2.attribute_type_id = 2 AND c.id = 506 AND h.expiry_date >= '2013-02-20 12:05:13' AND h.id > 1
When you need more speed in searching data you should take a look at Solr or Sphinx. With this index servers you can index your MySQL-Data and query them. Its much more faster then MySQL.
There's quite a lot wrong in your first query: The first 7 LEFT JOINs should be INNER JOINs. For qitz3_attributes you should consider normalizing the data less aggressively (use multiple columns instead of multiple rows to describe the data.
Select all possible children with parent in mysql
I have a users table. I have a certifications table. Each user can have multiple certifications. Certifications has a user_id foreign key. How may I select a user as well as all of their certifications in one query? How may I select users that have certifications? users table: CREATE TABLE `users` ( `id` int(11) unsigned NOT NULL auto_increment, `username` varchar(24) default NULL, `displayname` varchar(24) default NULL, `email` varchar(64) default NULL, `password` text, `signup_date` int(11) default NULL, `signup_ip` varchar(15) default NULL, `hash` text, `verified` tinyint(1) default '0', `last_login` int(11) default NULL, `logins` int(11) default NULL, `status` text, `recovery_hash` text, `recovery_initiated` int(11) default NULL, `last_updated` int(11) default NULL, `signup_method` text, `signup_question` int(11) default NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; certifications table: CREATE TABLE `certifications` ( `id` int(11) unsigned NOT NULL auto_increment, `user_id` int(11) unsigned NOT NULL, `number` varchar(128) default NULL, `board` varchar(128) default NULL, `company` varchar(128) default NULL, `website` varchar(128) default NULL, PRIMARY KEY (`id`), KEY `user_id` (`user_id`), CONSTRAINT `certifications_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; Thank you for reading.
How may I select a user as well as all of their certifications in one query? SELECT * FROM certifivations C LEFT JOIN users U ON C.user_id = U.id WHERE U.id=USERID How may I select users that have certifications? SELECT * FROM certifivations C JOIN users U ON C.user_id = U.id GROUP BY U.id
Get all the certifications of user with id of 1 by using a join. SELECT b.id as certification_id FROM users AS a LEFT JOIN certifications AS b ON a.id = b.user_id WHERE a.id = 1; Get all the users that have certifications using an inner join. All users without certs will drop out. SELECT a.id as users_with_certifications FROM users as a JOIN certifications AS b ON a.id = b.user_id;