Już drugi dzień próbuję wymyśleć jak możnaby zapisać poniższe zapytanie z użyciem joinów zamiast podzapytań i nie mogę znaleźć rozwiazania.

  1. SELECT b.buildingId, b.buildingName, cb.buildingLevel
  2. FROM buildings b
  3. LEFT JOIN citybuildings cb ON b.buildingId = cb.buildingId AND cb.cityId =$cityId
  4. WHERE NOT EXISTS (
  5. SELECT 1
  6. FROM buildingsrequirements br
  7. WHERE br.buildingId = b.buildingId AND NOT EXISTS
  8. (
  9. SELECT 1
  10. FROM citybuildings cb1
  11. WHERE br.bui_buildingId=cb1.buildingId AND cb1.cityId = cb.cityId
  12. )
  13. )
  14. ORDER BY b.buildingName

Wydaje mi się, że przy użyciu joinów wyglądałoby to prościej.
W zapytaniu chodzi o pobranie budynków które już zostały zbudowane w danym mieście wraz z ich poziomami, oraz budynków, które wolno zbudować (wtedy poziom np. null), warunek - muszą być już zbudowane wszystkie inne budynki wymagane dla nich.

Struktura
  1. CREATE TABLE `buildings` (
  2. `buildingId` int(3) NOT NULL AUTO_INCREMENT,
  3. `buildingName` varchar(24) NOT NULL,
  4. PRIMARY KEY (`buildingId`)
  5. ) ENGINE=MyISAM DEFAULT CHARSET=latin2 AUTO_INCREMENT=14 ;
  6.  
  7. -- --------------------------------------------------------
  8.  
  9.  
  10. CREATE TABLE `buildingsrequirements` (
  11. `buildingId` int(3) NOT NULL,
  12. `bui_buildingId` int(3) NOT NULL,
  13. KEY `FK_Relationship_2` (`bui_buildingId`),
  14. KEY `FK_Relationship_3` (`buildingId`)
  15. ) ENGINE=MyISAM DEFAULT CHARSET=latin2;
  16.  
  17. -- --------------------------------------------------------
  18.  
  19.  
  20.  
  21. CREATE TABLE `citybuildings` (
  22. `cityId` int(7) NOT NULL,
  23. `buildingId` int(3) NOT NULL,
  24. `buildingLevel` tinyint(4) NOT NULL,
  25. KEY `FK_Relationship_4` (`cityId`),
  26. KEY `FK_Relationship_5` (`buildingId`)