I wrote a following statement:
SELECT b.buildingId, b.buildingName, (
SELECT cb.buildinglevel
FROM citybuildings cb
WHERE cb.cityId =$cityId
AND b.buildingId = cb.buildingId
) AS buildingLevel
FROM buildings b
WHERE (
SELECT count( * )
FROM buildingsrequirements br
WHERE br.buildingId = b.buildingId
AND br.bui_buildingId NOT
IN (
SELECT cb.buildingId
FROM citybuildings cb
WHERE cb.cityId =$cityId
)
) =0
ORDER BY b.buildingName
Tt works fine, however in my opinion it is a bit too complicated and i am looking for a way to make it simplier, and I have no idea. For example it uses three subqueries and also I have to use variable $cityId two times, so it gets difficult to maintain and understand.
The purpose of this statement is to get a list of all buildings in the given city with their level, together with a list of buildings that can be build in the city and all buildings required for them have already been build. The level for those would be null.
That is the part of database structure:
CREATE TABLE `buildings` (
`buildingId` int(3) NOT NULL auto_increment,
`buildingName` varchar(24) NOT NULL,
PRIMARY KEY (`buildingId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin2 AUTO_INCREMENT=14 ;
-- --------------------------------------------------------
CREATE TABLE `buildingsrequirements` (
`buildingId` int(3) NOT NULL,
`bui_buildingId` int(3) NOT NULL,
KEY `FK_Relationship_2` (`bui_buildingId`),
KEY `FK_Relationship_3` (`buildingId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin2;
-- --------------------------------------------------------
CREATE TABLE `citybuildings` (
`cityId` int(7) NOT NULL,
`buildingId` int(3) NOT NULL,
`buildingLevel` tinyint(4) NOT NULL,
KEY `FK_Relationship_4` (`cityId`),
KEY `FK_Relationship_5` (`buildingId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin2;