inner joining on a update - mysql

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 = ?

Related

MySQL performance with nested sub query

I have two tables messages and members. I tried joining tables without having a nested query but it does not reflect the join on members. So, I initially thought that I could do the following
SELECT M1.*, COUNT(M2.emid) AS replies FROM messages M1
LEFT JOIN messages M2
ON M2.thread = M1.emid
INNER JOIN members M
ON M.meid = M1.emitter
WHERE
M1.thread is NULL AND
M1.receiver = 2
GROUP BY
M1.emid
but it does not seem to join the corresponding member. Then I tried this and it gives me the result that I need but I would like to know if there is a way to accomplish the same result using joins without the nested query
SELECT * FROM (
SELECT M1.*, COUNT(M2.emid) AS replies FROM messages M1
LEFT JOIN messages M2
ON M2.thread = M1.emid
WHERE
M1.thread is NULL AND
M1.receiver = 2
GROUP BY
M1.emid
) O INNER JOIN members M ON O.receiver = M.meid
-- Table structure for table members
CREATE TABLE `members` (
`meid` bigint(64) NOT NULL,
`name` varchar(32) DEFAULT NULL,
`lastname` varchar(32) DEFAULT NULL,
`email` varchar(128) NOT NULL,
`mobile` char(10) DEFAULT NULL,
`college` bigint(64) NOT NULL,
`major` bigint(64) NOT NULL,
`password` varchar(256) NOT NULL,
`oauth` varchar(128) DEFAULT NULL,
`confirmed` tinyint(4) DEFAULT NULL,
`active` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`joined` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- Table structure for table messages
CREATE TABLE `messages` (
`emid` bigint(20) NOT NULL,
`emitter` bigint(20) NOT NULL,
`receiver` bigint(20) NOT NULL,
`thread` bigint(20) DEFAULT NULL,
`opened` tinyint(4) DEFAULT '0',
`message` blob NOT NULL,
`timecard` datetime DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

sql can't figure out the query

I have three tables:
CREATE TABLE IF NOT EXISTS `contacts` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`providerId` int(10) unsigned NOT NULL DEFAULT '0',
`requestId` int(10) unsigned NOT NULL DEFAULT '0',
`status` binary(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
)
CREATE TABLE IF NOT EXISTS `messages` (
`id` int(255) NOT NULL AUTO_INCREMENT,
`fromuid` int(255) NOT NULL,
`touid` int(255) NOT NULL,
`sentdt` datetime NOT NULL,
`read` tinyint(1) NOT NULL DEFAULT '0',
`readdt` datetime DEFAULT NULL,
`messagetext` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`),
KEY `id` (`id`)
)
CREATE TABLE IF NOT EXISTS `users` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`email` varchar(255) DEFAULT NULL,
`mobile` varchar(15) NOT NULL,
`password` varchar(255) NOT NULL,
`city` varchar(255) NOT NULL,
`zip` varchar(15) DEFAULT NULL,
`device` varchar(50) DEFAULT NULL,
`version` varchar(10) DEFAULT NULL,
`photo` varchar(255) DEFAULT NULL,
`created` datetime NOT NULL,
`live` enum('0','1') NOT NULL DEFAULT '1',
`authenticationTime` datetime NOT NULL,
`userKey` varchar(255) DEFAULT NULL,
`IP` varchar(50) DEFAULT NULL,
`port` int(10) DEFAULT '0',
PRIMARY KEY (`id`),
KEY `firstname` (`mobile`,`city`,`zip`)
)
And this SQL query that finds out friends/contacts for specified user (user id 1 in this case):
SELECT u.id
,u.mobile
,u.name
,(NOW() - u.authenticationTime) AS authenticateTimeDifference
,u.IP
,f.providerid
,f.requestid
,f.status
,u.port
FROM contacts f
LEFT JOIN users u ON u.id =
IF (
f.providerid = 1
,f.requestid
,f.providerid
) WHERE (
f.providerid = 1
AND f.status = 1
)
OR f.requestid = 1
That works fine but I want to be able to also join messages table and show user's friends/contacts who have talked latest (meaning latest conversations first) with order by messages.sentdt desc option but I am unable to figure out how to do that, I tried all joins but none worked :(
Your help will be greatly appreciated. Thanks
Update
Here is sample data above query returns:
In that same resultset, I want to be able to sort based on order by messages.sentdt desc but I am not sure how to pull that in and sort resultset by latest message first
Try this:
select u.id
, u.mobile
, u.name
, (NOW() - u.authenticationTime) as authenticateTimeDifference
, u.IP
, f.providerid
, f.requestid
, f.status
, u.port
from contacts f
left join users u
on u.id = if (f.providerid = 1, f.requestid, f.providerid)
left join (select fromuid, max(sentdt) as sentdt from messages group by fromuid) m
on m.fromuid = if (f.providerid = 1, f.providerid, f.requestid)
where (f.providerid = 1 and f.status = 1)
or f.requestid = 1
order by m.sentdt

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;

Complex mySQL Query (again)

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.