Complex mySQL Query (again) - mysql

My apologies that the question title is not more specific.
I am working on a system that involves stock control and membership records. The current problem relates to the 'membership packs' that are given to new members on joining; there are a variety of membership types and each one gets a pack with several items in, no two packs are exactly the same but there is some overlap with some products being used in more than one pack. I need to calculate the number of each product that is used in a given batch of new members.
I can create a query that gives me the total of different membership types in a batch.
I can create a query that give me the total of each product required to make one of each of those packs.
I need to create a query that is a combination of both.
The query that gives the total of each type in a batch:
SELECT COUNT(*) AS theCount, membershipPackType
FROM inputBatches
LEFT JOIN inputActions ON inputActionID = inputBatchAction
LEFT JOIN members ON memberID = inputBatchMemberID
LEFT JOIN membershipPacks ON membershipPackType = memberMembershipType
LEFT JOIN memPack ON memPackInputBatch = inputBatchID
WHERE memPackBookedOut = 'U'
AND inputActionAbbr <> 'E'
GROUP BY membershipPackType
ORDER BY membershipPackType;
This query produces the output at the top of the linked image:
The query that gives the total of each product to make one of each of the types from the result of the above query:
SELECT COUNT(*) AS theCount, stockItem
FROM membershipPackItems
LEFT JOIN membershipPacks ON membershipPackNumber = membershipPackType
LEFT JOIN stock ON stockNumber = membershipPackItemNo
WHERE membershipPackNumber = 11 OR membershipPackNumber = 12 OR membershipPackNumber = 13 OR membershipPackNumber = 14 OR membershipPackNumber = 23 OR membershipPackNumber = 24 OR membershipPackNumber = 25
GROUP BY stockItem
ORDER BY stockNumber;
This query produces the output at the bottom of this image:
http://www.kidderminsterharriers.com/images/query4.png
If I could combine the two queries then I wouldn't have the WHERE clause in the second query that is hard-coded like that. Also, what this second query doesn't allow for is that the membershipPackItems table includes a field for quantity; it assumes that the quantity of each item per pack is 1.
The ultimate aim is to have query that outputs in a similar fashion to the second query but that the column that is currently 'theCount' is a total allows for the number of each item in the pack (ie more than 1 if needed) and then multiplied up by the number of packs in the batch; in this case those items that currently have a count of 7 (there's 7 different types in this batch and those items appear in all of them) would be 62 (there's 62 members total in this batch).
This is the structure of the data tables used:
CREATE TABLE membershipPackItems (
membershipPackItemID int(10) NOT NULL auto_increment,
membershipPackNumber int(7) NOT NULL,
membershipPackItemNo varchar(6) NOT NULL,
membershipPackItemQty int(7) NOT NULL,
PRIMARY KEY (membershipPackItemID)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=71 ;
CREATE TABLE membershipPacks (
membershipPackID int(5) NOT NULL auto_increment,
membershipPackTitle varchar(50) default NULL,
membershipPackType int(5) default NULL,
PRIMARY KEY (membershipPackID)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=13 ;
CREATE TABLE stock (
stockID int(10) NOT NULL auto_increment,
stockNumber int(8) NOT NULL,
stockItem varchar(50) NOT NULL,
stockNominalNo int(14) NOT NULL,
stockVATNo int(3) NOT NULL,
stockDecLevel varchar(1) NOT NULL,
stockPeriodSold int(14) NOT NULL,
stockPeriodSoldValue float NOT NULL,
stockPPurchased int(14) NOT NULL,
stockYTDSold int(14) NOT NULL,
stockYTDSoldValue float NOT NULL,
stockYTDPurchased int(14) NOT NULL,
stockDefectLevel int(14) NOT NULL,
stockCurrentLevel int(14) NOT NULL,
stockReOrderLevel int(14) NOT NULL,
stockHolding int(14) NOT NULL,
stockBackOrderQty int(14) NOT NULL,
stockRetail float NOT NULL,
stockCost float NOT NULL,
stockOrdered int(14) NOT NULL,
stockSupplierNo int(7) NOT NULL,
stockSupplierStockNo varchar(20) NOT NULL,
stockDeliveryDate date NOT NULL,
stockDeleted varchar(1) NOT NULL,
stockAllowedLeaps varchar(1) NOT NULL,
stockCount int(14) NOT NULL,
stockCountDate date NOT NULL,
stockCountComment varchar(30) NOT NULL,
stockGroup1 varchar(4) NOT NULL,
stockGroup2 varchar(4) NOT NULL,
stockNewStockNo varchar(6) NOT NULL,
stockStatus int(3) NOT NULL,
PRIMARY KEY (stockID)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1779 ;
CREATE TABLE inputBatches (
inputBatchID int(10) NOT NULL auto_increment,
inputBatchInputNumber int(8) NOT NULL,
inputBatchMemberID int(8) NOT NULL,
inputBatchAction int(5) NOT NULL,
inputBatchDate date NOT NULL,
PRIMARY KEY (inputBatchID)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=88 ;
CREATE TABLE members (
memberID int(6) NOT NULL auto_increment,
memberCentre int(5) NOT NULL,
memberMembershipNo int(15) NOT NULL,
memberSurname varchar(50) NOT NULL,
memberForename varchar(50) NOT NULL,
memberSecondName varchar(50) NOT NULL,
memberParentTitle int(3) NOT NULL,
memberParentSurname varchar(50) NOT NULL,
memberParentForename varchar(50) NOT NULL,
memberStreet1 varchar(100) NOT NULL,
memberStreet2 varchar(100) NOT NULL,
memberTown varchar(50) NOT NULL,
memberCounty varchar(20) NOT NULL,
memberPostcode varchar(10) NOT NULL,
memberPhoneSTD varchar(6) NOT NULL,
memberPhone varchar(20) NOT NULL,
memberMobile varchar(20) NOT NULL,
memberEmail varchar(255) NOT NULL,
memberDOB date NOT NULL,
memberJoined date NOT NULL,
memberGender enum('m','f') NOT NULL,
memberSibling enum('no','yes') NOT NULL default 'no',
memberMembershipType int(3) NOT NULL,
memberSpecNeedsNo int(5) NOT NULL,
memberPromoNo int(5) NOT NULL,
memberDataProtect enum('no','yes') NOT NULL default 'no',
memberReceived date NOT NULL,
memberMemberType int(4) NOT NULL,
memberSendPack enum('no','yes') NOT NULL default 'no',
memberSendGift enum('no','yes') NOT NULL default 'no',
memberExpire date NOT NULL,
memberDespatched date NOT NULL,
memberInputNo int(10) NOT NULL,
memberSSC int(10) NOT NULL,
memberPrevStreet1 varchar(100) NOT NULL,
memberPrevStreet2 varchar(100) NOT NULL,
memberPrevTown varchar(50) NOT NULL,
memberPrevCounty varchar(20) NOT NULL,
memberPrevPostcode varchar(10) NOT NULL,
memberPrevCentre varchar(5) NOT NULL,
memberInvoiced float NOT NULL,
memberPaid float NOT NULL,
memberSpecNeedsString varchar(255) NOT NULL,
memberNotes mediumtext,
memberMembershipYear int(3) default '1',
PRIMARY KEY (memberID),
UNIQUE KEY memberMembershipNo (memberMembershipNo),
KEY memberFullName (memberSurname,memberForename),
KEY memberSurname (memberSurname),
KEY memberForename (memberForename)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=631747 ;
CREATE TABLE memPack (
memPackID int(10) NOT NULL auto_increment,
memPackBookedOut varchar(1) NOT NULL,
memPackDate date NOT NULL,
memPackMembershipNo int(14) NOT NULL,
memPackLicenseeNo int(7) NOT NULL,
memPackMemTypeNo int(7) NOT NULL,
memPackInputNumber int(13) NOT NULL,
memPackInputBatch int(10) NOT NULL,
memPackCentreNo int(14) NOT NULL,
PRIMARY KEY (memPackID)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=13675 ;

You can combine both queries by joining them on membershipPackType.
The INNER JOIN with your first query takes care of the hardcoded WHERE clause.
SQL Statement
SELECT COUNT(*) AS theCount
, stockItem
FROM membershipPackItems
LEFT JOIN membershipPacks ON membershipPackNumber = membershipPackType
LEFT JOIN stock ON stockNumber = membershipPackItemNo
INNER JOIN (
SELECT COUNT(*) AS theCount
, membershipPackType
FROM inputBatches
LEFT JOIN inputActions ON inputActionID = inputBatchAction
LEFT JOIN members ON memberID = inputBatchMemberID
LEFT JOIN membershipPacks ON membershipPackType = memberMembershipType
LEFT JOIN memPack ON memPackInputBatch = inputBatchID
WHERE memPackBookedOut = 'U'
AND inputActionAbbr <> 'E'
GROUP BY
membershipPackType
) cnt ON cnt.membershipPackType = membershipPackItems.membershipPackType
GROUP BY stockItem
ORDER BY stockNumber;
Edit
I have trimmed down the scripts and altered your first query as below in an effort to try and understand what is what.
If you provide some scripts to fill the tables with some data (preferably the data that should become the outputs you've posted), I am willing to have another look at it, otherwise, this is as far as I am prepared to go with this, sorry.
Note: that you should definitly strive for a consistent naming scheme. membershipPackItemNo in one table is stockNumber in an other, Packtype links with PackNumber, memPackInputBatch links with inputBatchID. If not for your own sanity, it would make it much easier for us to figure out what is what.
Note: the scripts have been changed for SQL Server. I don't have a MySQL running.
CREATE TABLE membershipPackItems (
membershipPackNumber INTEGER NOT NULL,
membershipPackItemNo varchar(6) NOT NULL,
)
CREATE TABLE membershipPacks (
membershipPackType INTEGER default NULL,
)
CREATE TABLE stock (
stockNumber INTEGER NOT NULL,
stockItem varchar(50) NOT NULL,
)
CREATE TABLE inputBatches (
inputBatchID INTEGER NOT NULL IDENTITY(1, 1),
inputBatchMemberID INTEGER NOT NULL,
inputBatchAction INTEGER NOT NULL,
)
CREATE TABLE members (
memberID INTEGER NOT NULL IDENTITY(1, 1),
memberMembershipType INTEGER NOT NULL,
)
CREATE TABLE memPack (
memPackBookedOut varchar(1) NOT NULL,
memPackInputBatch INTEGER NOT NULL,
)
SELECT COUNT(*) AS theCount, st.stockItem
FROM stock st
LEFT OUTER JOIN membershipPackItems mpi ON mpi.membershipPackItemNo = st.stockNumber
LEFT OUTER JOIN membershipPacks mp ON mp.membershipPackType = mpi.membershipPackNumber
WHERE mpi.membershipPackNumber = 11
GROUP BY stockItem

LOL PSEUDOCODE
Get the StockItem, and its quantity associated for each
membershipPackType. The ff is just a pseudocode but I am thinking that
you can create the actual SQL query to get what I am trying to get at.
MembershipPackType_Stock = SELECT membershipPackType,
StockItem, MembershipPackItemQty
FROM MembershipPackItems
LEFT JOIN MembershipPacks ON ...
LEFT JOIN stock ON ...
Get the number of members for each MembershipPackType in a Batch. The ff SQL query is directly taken from your post.
MembershipPackType_Count = SELECT COUNT(*) AS MemberCount, membershipPackType
FROM inputBatches
LEFT JOIN inputActions ON inputActionID = inputBatchAction
LEFT JOIN members ON memberID = inputBatchMemberID
LEFT JOIN membershipPacks ON membershipPackType = memberMembershipType
LEFT JOIN memPack ON memPackInputBatch = inputBatchID
WHERE memPackBookedOut = 'U'
AND inputActionAbbr <> 'E'
GROUP BY membershipPackType
ORDER BY membershipPackType;
3 Then you can easily join MembershipPackType_Stock and MembershipPackType_Count to get the total number for each StockItem. Once again, the ff is just a pseudocode but I hope that you'll get the idea.
SELECT StockItem, SUM( MemberCount * MembershipPackItemQty)
FROM MembershipPackType_Stock JOIN MembershipPackType_Count
ON MembershipPackType = ...
GROUP BY StockItem
I am not sure if this is what you are asking, but if I understand your question correctly, I think this is it.

Related

multi field Group by in mysql with 0 result

let suppose I have the following tables
Listing Table
`listing` (
`fact_listing_id` INT(11) NOT NULL,
`region_id` INT(11) NOT NULL,
`created_at_date_id` INT(11) NOT NULL,
`category_id` INT(11) NOT NULL,
PRIMARY KEY (`fact_listing_id`),
)
Dim Category Table
`dim_category` (
`category_id` INT(11) NOT NULL,
`category_name` VARCHAR(100) NOT NULL,
`parent_category_id` INT(11) NULL,
`parent_category_name` VARCHAR(100) NULL,
PRIMARY KEY (`category_id`),
)
Dim Region Table
`dim_region` (
`region_id` INT(11) NOT NULL,
`region_name` VARCHAR(80) DEFAULT NULL,
PRIMARY KEY (`region_id`)
)
Dim Date Table
`dim_date` (
`date_id` INT(11) NOT NULL, -- date_key
`date` DATE,
`month` INT(11) NULL,
`day_of_month` INT(11) NULL,
`day_of_week` INT(11) NULL,
`week_of_month` INT(11) NULL,
`year` INT(11) NULL,
`quarter` INT(11) NULL,
PRIMARY KEY (`date_id`)
)
and now I want have a query to get count the number of listings in each category, in each region and each day by grouping on three fields, 'region_id','category_id' and 'date_id'
for one dimension, I mean grouping on one dimension it works correctly with the following query
select
count(fl.fact_listing_id) as Count
, dr.region_id
from fact_listing fl
right JOIN dim_region dr on fl.region_id = dr.region_id
group by
dr.region_id;
BUT when I try the following query the results aren't as I expecting
select
count(fl.fact_listing_id) as Count
, dr.region_id
, dc.category_id
, fl.created_at_date_id
from fact_listing fl
right JOIN dim_region dr on fl.region_id = dr.region_id
right JOIN dim_category dc on fl.category_id = dc.category_id
right JOIN dim_date dd on fl.created_at_date_id = dd.date_id
group by
fl.created_at_date_id
,dr.region_id
,dc.category_id;
I want the row which has 0-row result comes in output results, in summary, if I have 10 regions, 20 category and 100 days( in date table ) the results should be 10 * 20 * 100 rows.
my question is something like MySQL Group by - Get columns with zero count but grouping on multiple fields( columns).

inner joining on a update

I am trying to check if the user owns a course, I am trying to do this by getting the transaction_id (someone who's applied to a course) and then left join the courses and check the course_user against a session where the transaction_course is equal to course id
My SQL
UPDATE training_transactions
LEFT JOIN training
ON training_transactions.training_transaction_id =
training.course_id
SET training_transactions.training_transaction_status = 'declined'
WHERE training_transactions.training_transaction_id = ?
AND training.course_user = ?
training_transaction:
CREATE TABLE IF NOT EXISTS `training_transactions` (
`training_transaction_id` int(11) NOT NULL,
`training_transaction_user` int(11) NOT NULL,
`training_transaction_course` int(11) NOT NULL,
`training_transaction_status` varchar(50) NOT NULL,
`training_transaction_enabled` varchar(50) NOT NULL DEFAULT 'enabled',
`training_transaction_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
training
CREATE TABLE IF NOT EXISTS `training` (
`course_id` int(11) NOT NULL,
`course_user` int(11) NOT NULL,
`course_type` varchar(255) NOT NULL,
`course_name` varchar(255) NOT NULL,
`course_location` varchar(255) NOT NULL,
`course_duration` varchar(255) NOT NULL,
`course_fitness_type` varchar(255) NOT NULL,
`course_instructor_name` varchar(255) NOT NULL,
`course_price` int(15) NOT NULL,
`course_start_date` date NOT NULL,
`course_max_attendees` int(8) NOT NULL,
`course_accommodation` varchar(255) NOT NULL,
`course_accommodation_price` varchar(255) NOT NULL,
`course_status` varchar(50) NOT NULL,
`course_enabled` varchar(10) NOT NULL DEFAULT 'enabled'
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=latin1;
So my question, how can I update if the transaction id matches the course_id and the user's session (below) matches the course_user?
Session::get('id') // user id
You should be testing training_transaction_course in the WHEN clause, not training_transaction_id. And you should use INNER JOIN, not LEFT JOIN; you only need LEFT JOIN if you need to get rows in the first table that have no matches in the second table.
UPDATE training_transactions AS tt
INNER JOIN training AS t ON tt.training_transaction_id = t.course_id
SET tt.training_transaction_status = 'declined'
WHERE tt.training_transaction_course = ?
AND t.course_user = ?

i get wrong results from mysql join query

I have 2 tables, that i want to join, one is rooms and another is reservations.
Basically I want to search for rooms which are not reserved (not in reservation table) and to get the details of those rooms (which are not in reservation table) from room table.
Here are my tables structure:
CREATE TABLE `room` (
`roomID` int(11) NOT NULL AUTO_INCREMENT,
`hotelID` int(11) NOT NULL,
`roomtypeID` int(11) NOT NULL,
`roomNumber` int(11) NOT NULL,
`roomName` varchar(255) NOT NULL,
`roomName_en` varchar(255) NOT NULL,
`roomDescription` text,
`roomDescription_en` text,
`roomSorder` int(11) NOT NULL,
`roomVisible` tinyint(4) NOT NULL,
PRIMARY KEY (`roomID`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8;
CREATE TABLE `reservation` (
`reservationID` int(11) NOT NULL AUTO_INCREMENT,
`customerID` int(11) NOT NULL,
`hotelID` int(11) NOT NULL,
`reservationCreatedOn` datetime NOT NULL,
`reservationCreatedFromIp` varchar(255) CHARACTER SET greek NOT NULL,
`reservationNumberOfAdults` tinyint(4) NOT NULL,
`reservationNumberOfChildrens` tinyint(4) NOT NULL,
`reservationArrivalDate` date NOT NULL,
`reservationDepartureDate` date NOT NULL,
`reservationCustomerComment` text CHARACTER SET greek,
PRIMARY KEY (`reservationID`)
) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8;
CREATE TABLE `reservationroom` (
`reservationroomID` int(11) NOT NULL AUTO_INCREMENT,
`reservationID` int(11) NOT NULL,
`hotelID` int(11) NOT NULL,
`roomID` int(11) NOT NULL,
PRIMARY KEY (`reservationroomID`)
) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8;
Here is the query that I have right now, which gives me wrong results:
SELECT * FROM room r
LEFT JOIN reservation re
ON r.hotelID = re.hotelID
WHERE re.hotelID = 13
AND NOT
(re.reservationArrivalDate >= '2014-07-07' AND re.reservationDepartureDate <= '2014-07-13')
I also have created a fiddle, with the data from both tables included:
http://sqlfiddle.com/#!2/4bb9ea/1
Any help will be deeply appreciated
Regards, John
i agree that room number was missed,
but query template should looks like
SELECT
*
FROM
room r
LEFT JOIN reservation re
ON r.hotelID = re.hotelID
WHERE r.hotelID = 2
AND NOT (
re.hotelID IS NOT NULL
AND re.reservationArrivalDate >= '2014-07-07'
AND re.reservationDepartureDate <= '2014-09-23'
) ;
You need change table in where statement from reservation to room. Also you need add re.hotelID to where statement as well, because on where statement you need check that record is not null ans only after try to check dates
Given the newly-added reservationroom table, consider using a NOT EXISTS sub-query to find rooms without reservations:
SELECT
*
FROM
room r
WHERE NOT EXISTS
(SELECT
*
FROM
reservationroom rr
WHERE
rr.reservationroomID = r.roomID
)

my join returns 0 results

I have to following 3 tables: room, reservation and reservationroom
Their structure is as follows:
CREATE TABLE `room` (
`roomID` int(11) NOT NULL AUTO_INCREMENT,
`hotelID` int(11) NOT NULL,
`roomtypeID` int(11) NOT NULL,
`roomNumber` int(11) NOT NULL,
`roomName` varchar(255) NOT NULL,
`roomName_en` varchar(255) NOT NULL,
`roomDescription` text,
`roomDescription_en` text,
`roomSorder` int(11) NOT NULL,
`roomVisible` tinyint(4) NOT NULL,
PRIMARY KEY (`roomID`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8;
CREATE TABLE `reservation` (
`reservationID` int(11) NOT NULL AUTO_INCREMENT,
`customerID` int(11) NOT NULL,
`hotelID` int(11) NOT NULL,
`reservationCreatedOn` datetime NOT NULL,
`reservationCreatedFromIp` varchar(255) CHARACTER SET greek NOT NULL,
`reservationNumberOfAdults` tinyint(4) NOT NULL,
`reservationNumberOfChildrens` tinyint(4) NOT NULL,
`reservationArrivalDate` date NOT NULL,
`reservationDepartureDate` date NOT NULL,
`reservationCustomerComment` text CHARACTER SET greek,
PRIMARY KEY (`reservationID`)
) ENGINE=InnoDB AUTO_INCREMENT=46 DEFAULT CHARSET=utf8;
CREATE TABLE `reservationroom` (
`reservationroomID` int(11) NOT NULL AUTO_INCREMENT,
`reservationID` int(11) NOT NULL,
`hotelID` int(11) NOT NULL,
`roomID` int(11) NOT NULL,
PRIMARY KEY (`reservationroomID`)
) ENGINE=InnoDB AUTO_INCREMENT=46 DEFAULT CHARSET=utf8;
(please note that foreign keys have been removed from create statements for sake of simplicity)
What I am trying to do: I want to get all rooms that are not reserved for specific dates, that is only the free rooms from the specific hotel (I have its ID)
Here is the query that I have right now:
SELECT r.* FROM room r
LEFT JOIN `reservationroom` rr
ON r.`hotelID` = rr.`hotelID`
AND r.`roomID` = rr.`roomID`
LEFT JOIN `reservation` re
ON rr.`reservationID` = re.`reservationID`
WHERE (rr.`reservationroomID` = ''
OR rr.`reservationroomID` IS NULL
AND re.`reservationArrivalDate` >= 2014-08-27
AND re.`reservationDepartureDate` <= 2014-08-29
AND r.`hotelID` = 10
AND r.`roomVisible` = 1);
This query now returns 0 results. It should return 9 records, since the hotel with ID = 10 has 9 rooms that are free (no resevations for specific dates exist in the reservation table)
Can anyone give me a hand with this please? I am trying to sort this out couple of hours, without any success.
You are using left join, so conditions on all but the first table should be in the on clauses. I think you want a query more like this:
SELECT r.*
FROM room r LEFT JOIN
`reservationroom` rr
ON r.`hotelID` = rr.`hotelID` AND
r.`roomID` = rr.`roomID` LEFT JOIN
`reservation` re
ON rr.`reservationID` = re.`reservationID` AND
re.`reservationArrivalDate` >= 2014-08-27 AND
re.`reservationDepartureDate` <= 2014-08-29
WHERE r.`hotelID` = 10 AND r.`roomVisible` = 1 AND re.reservationID is null;
I'm not sure what the comparison is to the empty string. It doesn't seem necessary for this purpose.

getting number of records from 2 tables - one to many relationship

I have problem with search query that i have to built on the fly to return records from the database.
I have 2 tables: adds andadds_filters`. For the sake of simplicity, i make the table adds shorter than it is, removing some of the (irrelevant) fields
My table structure:
CREATE TABLE IF NOT EXISTS `adds` (
`addid` int(11) NOT NULL AUTO_INCREMENT,
`memberid` int(11) NOT NULL,
`isnew` int(11) NOT NULL,
`catid` int(11) NOT NULL,
`manufacturerid` int(11) NOT NULL,
`modelid` varchar(255) DEFAULT NULL,
`colorid` int(11) DEFAULT NULL,
`geographicareaid` int(45) NOT NULL,
`addtypeid` varchar(45) NOT NULL,
`addcreatedon` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`addvalidfrom` date NOT NULL,
`addvaliduntil` date NOT NULL,
`addcreatedfromip` varchar(255) NOT NULL,
`yearofmanufacturing` varchar(255) DEFAULT NULL,
`monthofmanufacturing` int(11) DEFAULT NULL,
`hoursused` int(11) DEFAULT NULL,
`cc2` int(11) DEFAULT NULL,
`horsepowers` int(11) DEFAULT NULL,
`metalic` tinyint(4) DEFAULT NULL,
`isdamaged` tinyint(4) DEFAULT NULL,
`price` float DEFAULT NULL,
`hasvat` tinyint(4) NOT NULL,
`canbenegotiated` tinyint(4) DEFAULT NULL,
`addtitle` varchar(255) DEFAULT NULL,
`addtext` text NOT NULL,
`youtubevideo` varchar(255) DEFAULT NULL,
`visible` tinyint(4) DEFAULT NULL,
`ff1` varchar(255) DEFAULT NULL,
`ff2` varchar(255) DEFAULT NULL,
`ff3` varchar(255) DEFAULT NULL,
`ff4` varchar(255) DEFAULT NULL,
PRIMARY KEY (`addid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=43 ;
CREATE TABLE IF NOT EXISTS `adds_filters` (
`addfilterid` int(11) NOT NULL AUTO_INCREMENT,
`addid` int(11) NOT NULL,
`filterid` int(11) NOT NULL,
PRIMARY KEY (`addfilterid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=45 ;
Here is the fiddle
Problem is that user can add more than one filter for each adds, that is if the
vehicle has AC,GPS, removable cabin and so on...This data is stored in the adds_filters. So, one add can have many filters.
How the query should look like when user choose that catid is 1, manufacturerid is 1 and then users check filters with ids
67 and 158 for example?
I would prefer view over the query, but i have no idea how can i build such view. Reason from preferring the view is that in such a case, i will be able to use select * instead of complicated queries...
Any help will be deeply appreciated.
With this table structure, you gonna need subqueries for each checked filterid, if you want filterids to be displayed.
Without displaying, you can just use DISTINCT and IN.
Here is the query without displaying filterids
SELECT DISTINCT a.*
FROM adds a
JOIN adds_filters f
ON a.`addid` = f.`addid`
WHERE a.`catid` = 1
AND a.`manufacturerid` = 1
AND f.`filterid` IN (67, 158);
Here is the query, that displays two different filterids:
SELECT t1.*, t2.filterid as filterid2
FROM
(
SELECT DISTINCT a.*,
f.`filterid`
FROM adds a
JOIN adds_filters f
ON a.`addid` = f.`addid`
WHERE a.`catid` = 1
AND a.`manufacturerid` = 1
AND f.`filterid` = 67
) t1
JOIN
(
SELECT DISTINCT a.`addid`,
f.`filterid`
FROM adds a
JOIN adds_filters f
ON a.`addid` = f.`addid`
WHERE a.`catid` = 1
AND a.`manufacturerid` = 1
AND f.`filterid` = 158
) t2
ON t1.addid = t2.addid;