I'm trying to figure out the calculation for finding the stock required and also display the volume output if it cant reach the max tresshold in this case volume '1000'.
I will try my best to explain it as plain as possible. (tables and columns are in dutch)
Example:
To produce a volume of 1000 I need multiple raw materials. The raw materials have different totals to go in the 'cooking pot' (and to reach 1000, aqua is added but thats a side note).
1000 is the base for calculating the numbers in the table receptgrondstoffen
First I have the table with the recipe called 'naam' (name)
table: recepten
CREATE TABLE `recepten` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`administratieid` int(11) NOT NULL DEFAULT 0,
`omzetgroepid` int(11) NOT NULL DEFAULT 0,
`artikelgroepid` int(11) NOT NULL DEFAULT 0,
`artikelnummer` int(11) NOT NULL DEFAULT 0 COMMENT 'gevuld vanuit snelstart',
`factornummer` varchar(20) NOT NULL,
`eannummer` varchar(20) NOT NULL,
`naam` varchar(255) NOT NULL,
`notitie` mediumtext NOT NULL,
`volume` decimal(10,5) NOT NULL DEFAULT 0.00000,
`onderzoek` int(1) NOT NULL DEFAULT 0,
`viscositeit` varchar(50) NOT NULL,
`phwaarde` varchar(50) NOT NULL,
`dichtheid` varchar(50) NOT NULL,
`thtmaanden` int(11) NOT NULL DEFAULT 0,
`voorraadcontrole` int(1) NOT NULL DEFAULT 0,
`drempelwaarde` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
INSERT INTO `recepten` (`id`,`administratieid`,`omzetgroepid`,`artikelgroepid`,`artikelnummer`,`factornummer`,`eannummer`,`naam`,`notitie`,`volume`,`onderzoek`,`viscositeit`,`phwaarde`,`dichtheid`,`thtmaanden`,`voorraadcontrole`,`drempelwaarde`) VALUES (1,0,0,702,300001,'122','','test','test',1000.00000,1,'1','2','3',36,0,1);
INSERT INTO `recepten` (`id`,`administratieid`,`omzetgroepid`,`artikelgroepid`,`artikelnummer`,`factornummer`,`eannummer`,`naam`,`notitie`,`volume`,`onderzoek`,`viscositeit`,`phwaarde`,`dichtheid`,`thtmaanden`,`voorraadcontrole`,`drempelwaarde`) VALUES (2,0,0,704,300002,'1234','','test1','test',1000.00000,1,'1','2','3',36,0,100);
Second tables are the recipe items that go into the 'cooking pot'. There are 2 raw material lines. Both have a number of 100 so for each volume of 1000, 100 units from both are required. If I change the volume to 100 then 10 units from both are required.
table: receptgrondstoffen
CREATE TABLE `receptgrondstoffen` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`receptid` int(11) NOT NULL DEFAULT 0,
`grondstofid` int(11) NOT NULL DEFAULT 0,
`aantal` decimal(10,5) NOT NULL DEFAULT 0.00000,
`percentage` decimal(10,5) NOT NULL DEFAULT 0.00000,
UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
INSERT INTO `receptgrondstoffen` (`id`,`receptid`,`grondstofid`,`aantal`,`percentage`) VALUES (2,1,1,100.00000,10.00000);
INSERT INTO `receptgrondstoffen` (`id`,`receptid`,`grondstofid`,`aantal`,`percentage`) VALUES (3,1,2,100.00000,10.00000);
The 'grondstofbatch' tables is the raw material quantity that's been bought
Table: grondstofbatch
CREATE TABLE `grondstofbatch` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`grondstofid` int(11) NOT NULL DEFAULT 0,
`leveranciersid` int(11) NOT NULL DEFAULT 0,
`batchnummer` varchar(50) NOT NULL,
`datum` int(10) NOT NULL DEFAULT 0,
`thtdatum` int(10) NOT NULL DEFAULT 0,
`voorraad` int(11) NOT NULL DEFAULT 0,
UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
INSERT INTO `grondstofbatch` (`id`,`grondstofid`,`leveranciersid`,`batchnummer`,`datum`,`thtdatum`,`voorraad`) VALUES (1,1,4,'1224-4',1662626077,1665266400,100);
INSERT INTO `grondstofbatch` (`id`,`grondstofid`,`leveranciersid`,`batchnummer`,`datum`,`thtdatum`,`voorraad`) VALUES (2,1,3,'#34423',1662626904,1663970400,300);
INSERT INTO `grondstofbatch` (`id`,`grondstofid`,`leveranciersid`,`batchnummer`,`datum`,`thtdatum`,`voorraad`) VALUES (3,2,3,'#00931',1662626904,1663970400,200);
Volume is the kicker.
What i want, if I use volume amount lets say in this case its 3000 I get a return that the max volume be created is X because not all raw materials are present.
The base is 1000 = 100 so for 3000 it is 300 and only 1 raw material has the required stock. So that means it will be max 2000 volume. And if there is no volume that can be produced then 0.
results;
CREATE TABLE `results` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`volume` int(11) NOT NULL,
`quantity_needed` mediumtext NOT NULL,
`stock` mediumtext NOT NULL,
`result` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
INSERT INTO `results` (`id`,`volume`,`quantity_needed`,`stock`,`result`) VALUES (1,1000,'100,100','400,200',1000);
INSERT INTO `results` (`id`,`volume`,`quantity_needed`,`stock`,`result`) VALUES (2,400,'100,100','400,200',2000);
INSERT INTO `results` (`id`,`volume`,`quantity_needed`,`stock`,`result`) VALUES (3,3000,'100,100','400,200',2000);
INSERT INTO `results` (`id`,`volume`,`quantity_needed`,`stock`,`result`) VALUES (4,500,'100,100','400,200',500);
INSERT INTO `results` (`id`,`volume`,`quantity_needed`,`stock`,`result`) VALUES (5,500,'50,75','400,200',500);
INSERT INTO `results` (`id`,`volume`,`quantity_needed`,`stock`,`result`) VALUES (6,500,'50,75','25,75',250);
INSERT INTO `results` (`id`,`volume`,`quantity_needed`,`stock`,`result`) VALUES (7,500,'30,30','25,75',416);
Hope there is a SQL wizard that can help me out.
I think you are looking for something like
SELECT r.id,
r.volume,
group_concat(rg.aantal ORDER BY rg.id SEPARATOR ',') quantity_needed,
group_concat(g.voorraad ORDER BY rg.id SEPARATOR ',') stock,
min(floor(g.voorraad/rg.aantal)) * r.volume result
FROM recepten r INNER JOIN receptgrondstoffen rg
on r.id = rg.receptid
inner join grondstofbatch g
on g.id = rg.grondstofid
GROUP BY r.id, r.volume
You can see it with your sample data in this fiddle.
(I am possibly misunderstanding your problem since your result data doesn't seem to match your sample data).
The idea here is that, for each recepten, calculate min(floor(grondstofbatch.voorraad/receptgrondstoffen.aantal)). Floor since we want an integer (e.g. if we need 100 units for the recipe and actually have 250 units, floor(250/100) = 2 possible batches). Min since we want the limiting factor (e.g. it doesn't matter if one item in the recipe has enough for 20 batches if another item only has enough for 1 batch).
Hopefully this is in the ballpark of what you're looking for.
Edited: To handle the case where to sum the available quantities I have changed the alias g to be a subquery using the grondstofid table (rather than just the straight grondstofid table). I also realize I was likely joining the grondstofid table incorrectly above (g.id = rg.grondstofid rather than g.grondstofid = rg.grondstofid).
SELECT r.id,
r.volume,
group_concat(rg.aantal ORDER BY rg.id SEPARATOR ',') quantity_needed,
group_concat(g.voorraad ORDER BY rg.id SEPARATOR ',') stock,
min(floor(g.voorraad/rg.aantal)) * r.volume result
FROM recepten r INNER JOIN receptgrondstoffen rg
on r.id = rg.receptid
inner join (SELECT grondstofid, sum(voorraad) voorraad FROM grondstofbatch GROUP BY grondstofid) g
on g.grondstofid = rg.grondstofid
GROUP BY r.id, r.volume
Please take a look at a fiddle of this version
I'm implementing a booking platform I have 3 tables:
"hotel" - to hold the hotel information
"hotel_room" - to hold room info per hotel
"hotel_room_price" - have the availability by date, number of rooms available and price
I want to search by start date and end date, local and number of rooms (each room have the number of adults and number of child)
Here is some example of my tables:
CREATE TABLE `hotel` (
`id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`rating` smallint(6) NOT NULL DEFAULT '3' COMMENT '0 - Not Rated | 1 - One Star | 2 - Two Stars | 3 - Three Stars | 4 - Four Stars | 5 - Five Stars',
`local` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `hotel_room` (
`id` int(11) NOT NULL,
`hotel_id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`max_capacity_adult` smallint(6) NOT NULL,
`max_capacity_child` smallint(6) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `hotel_room` ADD CONSTRAINT `fk_hotel_room_hotel_id` FOREIGN KEY (`hotel_id`) REFERENCES `hotel` (`id`) ON DELETE CASCADE;
CREATE TABLE `hotel_room_price` (
`id` int(11) NOT NULL,
`hotel_room_id` int(11) NOT NULL,
`price_adult` decimal(20,2) DEFAULT NULL,
`price_child` decimal(20,2) DEFAULT NULL,
`quantity` int(11) NOT NULL DEFAULT '1' COMMENT 'available rooms, 0 if there is no more available',
`date` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `hotel_room_price` ADD CONSTRAINT `fk_hotel_room_price_hotel_room_id` FOREIGN KEY (`hotel_room_id`) REFERENCES `hotel_room` (`id`) ON DELETE CASCADE;
What is the better approach get the available rooms when a user search, one note it is possible to search for multiple rooms for example:
start_date = 2019-06-25
end_date = 2019-06-29
local = "Tomar"
Room=[
[
nr_adults = 2,
nr_children=1
],
[
nr_adults = 4,
nr_children=0
]
]
I think first thing to do it check only hotels from the right local then check if the room can hold the number of adults and children if yes check for availability.
I'm with lot of problems to create a query or multiple queries to handle this in the right way.
You can check and example of my database here http://sqlfiddle.com/#!9/458be2c
Here is query that selects all room ID's available in a given time frame. In this instance I picked June 26- June 28. This should be a good starting point for the rest of the query.
SELECT hotel_room_id
FROM hotel_room_price
WHERE date between '2019-06-26' AND '2019-06-28'
AND quantity > 0
GROUP BY hotel_room_id
HAVING COUNT(*) > DATEDIFF('2019-06-28', '2019-06-26')
Here is a somewhat hacky query to get some of the information about the rooms. Note there is not functionality for searching for multiple rooms in this sample:
SELECT h.name AS Name, h.rating AS Rating, sq.name AS Type
FROM hotel h
INNER JOIN
(SELECT *
FROM hotel_room
WHERE hotel_room.id IN
(SELECT hotel_room_id
FROM hotel_room_price
WHERE date between '[START DATE]' AND '[END DATE]'
AND quantity > 0
GROUP BY hotel_room_id
HAVING COUNT(*) > DATEDIFF('[END DATE]', '[START DATE]'))
AND max_capacity_child >= [CHILD COUNT]
AND max_capacity_adult >= [ADULT COUNT]) sq
ON h.id = sq.hotel_id
WHERE h.local = "[LOCATION]"
I've created a database to store movies data. My tables are the following:
movies:
CREATE TABLE IF NOT EXISTS `movies` (
`movieId` int(11) NOT NULL AUTO_INCREMENT,
`imdbId` varchar(255) DEFAULT NULL,
`imdbRating` float DEFAULT NULL,
`movieTitle` varchar(255) NOT NULL,
`movieLength` varchar(255) NOT NULL,
`imdbRatingCount` varchar(255) NOT NULL,
`poster` varchar(255) NOT NULL,
`year` varchar(255) NOT NULL,
PRIMARY KEY (`movieId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
I have a table in which i store movie actors:
CREATE TABLE IF NOT EXISTS `actors` (
`actorId` int(10) NOT NULL AUTO_INCREMENT,
`actorName` varchar(255) NOT NULL,
PRIMARY KEY (`actorId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
And one other in which i store the relation between the movies and actors: (movieActor)
CREATE TABLE IF NOT EXISTS `movieActor` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`movieId` int(10) NOT NULL,
`actorId` int(10) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Now when i want to select a list of movies in which are the selected actors my query is:
SELECT *
FROM movies m inner join
(SELECT movieId FROM movieActor WHERE actorId IN(1,2,3) GROUP BY movieId having count(*) = 3) ma ON m.movieId = ma.movieId
WHERE imdbRating IS NOT NULL ORDER BY imdbRating DESC
This is working perfectly, but i don't know that this is the optimal table structure and query to accomplish this. Are there any better table structure to store data or query the list?
First of all, use indexes on your tables. In my opinion it should be useful to have 3 indexes on movieActor. MovieId - ActorID - MovieIdActorId.
Second try tu use foreign keys. These help to identify the best execution plan for your dbs.
Third try to avoid generating temp tables in your execution plan of your query. Subselects often creates temp tables which are used when the database has to temporarily save something in the RAM. To check this, write EXPLAIN in front of goer query.
I would write it like this:
SELECT m.*, movieActor
FROM movies m inner join
movieActor ma ON m.movieId = ma.movieId
WHERE imdbRating IS NOT NULL
and actorId IN(1,2,3)
GROUP BY movieId
having count(*) = 3)
ORDER BY imdbRating DESC
(Not tested)
Just try to optimize it with the EXPLAIN keyword. It also can help you to create the right indexes.
I have a query that is executed in 35s, which is waaaaay too long.
Here are the 3 tables concerned by the query (each table is approx. 13000 lines long, and should be much longer in the future) :
Table 1 : Domains
CREATE TABLE IF NOT EXISTS `domain` (
`id_domain` int(11) NOT NULL AUTO_INCREMENT,
`domain_domain` varchar(255) NOT NULL,
`projet_domain` int(11) NOT NULL,
`date_crea_domain` int(11) NOT NULL,
`date_expi_domain` int(11) NOT NULL,
`active_domain` tinyint(1) NOT NULL,
`remarques_domain` text NOT NULL,
PRIMARY KEY (`id_domain`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Table 2 : Keywords
CREATE TABLE IF NOT EXISTS `kw` (
`id_kw` int(11) NOT NULL AUTO_INCREMENT,
`kw_kw` varchar(255) NOT NULL,
`clics_kw` int(11) NOT NULL,
`cpc_kw` float(11,3) NOT NULL,
`date_kw` int(11) NOT NULL,
PRIMARY KEY (`id_kw`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Table 3 : Linking between domain and keyword
CREATE TABLE IF NOT EXISTS `kw_domain` (
`id_kd` int(11) NOT NULL AUTO_INCREMENT,
`kw_kd` int(11) NOT NULL,
`domain_kd` int(11) NOT NULL,
`selected_kd` tinyint(1) NOT NULL,
PRIMARY KEY (`id_kd`),
KEY `kw_to_domain` (`kw_kd`,`domain_kd`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
The query is as follows :
SELECT ng.*, kd.*, kg.*
FROM domain ng
LEFT JOIN kw_domain kd ON kd.domain_kd = ng.id_domain
LEFT JOIN kw kg ON kg.id_kw = kd.kw_kd
GROUP BY ng.id_domain
ORDER BY kd.selected_kd DESC, kd.id_kd DESC
Basically, it selects all domains, with, for each one of these domains, the last associated keyword.
Does anyone have an idea on how to optimize the tables or the query ?
The following will get the last keyword, according to your logic:
select ng.*,
(select kw_kd
from kw_domain kd
where kd.domain_kd = ng.id_domain and kd.selected_kd = 1
order by kd.id_kd desc
limit 1
) as kw_kd
from domain ng;
For performance, you want an index on kw_domain(domain_kd, selected_kd, kw_kd). In this case, the order of the fields matters.
You can use this as a subquery to get more information about the keyword:
select ng.*, kg.*
from (select ng.*,
(select kw_kd
from kw_domain kd
where kd.domain_kd = ng.id_domain and kd.selected_kd = 1
order by kd.id_kd desc
limit 1
) as kw_kd
from domain ng
) ng left join
kw kg
on kg.id_kw = ng.kw_kd;
In MySQL, group by can have poor performance, so this might work better, particularly with the right indexes.
I'm trying to SELECT, and get a unique result set, from a MySQL database, as shown below. My problem is, I think, I don't understand LEFT Joins well enough. Or, maybe I need to use a different Join approach.
Here's a description of the database.
tbAdult (Adults) have x number of tbchild (Children) , and uses a cross-ref table called tbadultchildxref. This table has an f-key to both Adult and Child. I have to use an x-ref table, because there's a many-to-many relationship between these two tables, and there's other data that's keep in the x-ref, which I have removed for simplicity.
In turn, each Child belongs to a Program (tblprogram).
Each Program has x number of Cameras (tblCamera). Again, I have to use an x-ref table between tblProgram and tblCamera due to a many-to-many relationship, and other reasons.
What I am trying to get at, is a unique list of Cameras for a given Parent.
For example, Parent 675 has three children, Child ID's 789,788, and 789. Those three children, in turn, belong to Program ID's 4, 5, and 6.
Program ID 4 has Camera ID's 1,2,3
Program ID 5 has Camera ID's 4,5,6
Program ID 6 has Camera ID's 1,6,7,8
What I would like the result set to be is 1,2,3,4,5,6,7,8
I have tried different combinations of SELECT DISTINCT, LEFT JOINS on the various x-ref tables, etc. but I just can't seem to get it.
My other problem, along the way, is I need to check the "Active" fields in Adult, Child, and Program to equal = 1 (true) for the result set.
Thanks in advance.
CREATE TABLE `tbladult` (
`pkAdultID` int(11) NOT NULL AUTO_INCREMENT,
`fldAdultActive` tinyint(1) DEFAULT '1',
`fldAdultLogin` varchar(30) DEFAULT NULL,
`fldAdultPassword` varchar(45) DEFAULT NULL,
`fldAdultFirstName` varchar(60) DEFAULT NULL,
`fldAdultLastName` varchar(60) DEFAULT NULL,
PRIMARY KEY (`pkAdultID`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
/*Table structure for table `tblchild` */
CREATE TABLE `tblchild` (
`pkChildID` int(11) NOT NULL AUTO_INCREMENT,
`fldChildActive` tinyint(4) DEFAULT NULL,
`fldChildFirstName` varchar(45) DEFAULT NULL,
`fldChildLastName` varchar(45) DEFAULT NULL,
`fkChildProgram` int(1) DEFAULT NULL,
PRIMARY KEY (`pkChildID`),
KEY `FK_tblchild` (`fkChildProgram`),
CONSTRAINT `FK_tblchild` FOREIGN KEY (`fkChildProgram`) REFERENCES `tblprogram` (`pkProgramID`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
/*Table structure for table `tbladultchildxref` */
CREATE TABLE `tbladultchildxref` (
`pkAdultChildxRefID` int(11) NOT NULL AUTO_INCREMENT,
`fldAdultChildxRefActive` tinyint(1) DEFAULT '1',
`fkAdultID` int(11) DEFAULT NULL,
`fkChildID` int(11) DEFAULT NULL,
PRIMARY KEY (`pkAdultChildxRefID`),
KEY `FK_tbladultchildxref` (`fkAdultID`),
KEY `FK_tbladultchildxref2` (`fkChildID`),
CONSTRAINT `FK_tbladultchildxref` FOREIGN KEY (`fkAdultID`) REFERENCES `tbladult` (`pkAdultID`),
CONSTRAINT `FK_tbladultchildxref2` FOREIGN KEY (`fkChildID`) REFERENCES `tblchild` (`pkChildID`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
/*Table structure for table `tblprogram` */
CREATE TABLE `tblprogram` (
`pkProgramID` int(11) NOT NULL AUTO_INCREMENT,
`fldProgamActive` tinyint(1) DEFAULT '1',
`fldProgramName` varchar(50) DEFAULT NULL,
PRIMARY KEY (`pkProgramID`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=latin1;
/*Table structure for table `tblcamera` */
CREATE TABLE `tblcamera` (
`pkCameraID` int(11) NOT NULL AUTO_INCREMENT,
`fldCameraName` varchar(50) DEFAULT NULL,
`fldCameralocation` varchar(50) DEFAULT NULL,
`fldCameraURL` varchar(250) DEFAULT NULL,
PRIMARY KEY (`pkCameraID`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;
/*Table structure for table `tblprogramcameraxref` */
CREATE TABLE `tblprogramcameraxref` (
`pkProgramCameraXrefID` int(11) NOT NULL AUTO_INCREMENT,
`fkProgramID` int(11) DEFAULT NULL,
`fkCameraID` int(11) DEFAULT NULL,
PRIMARY KEY (`pkProgramCameraXrefID`),
KEY `FK_tblprogramcameraxref` (`fkProgramID`),
KEY `FK_camerasforprograms` (`fkCameraID`),
CONSTRAINT `FK_camerasforprograms` FOREIGN KEY (`fkCameraID`) REFERENCES `tblcamera` (`pkCameraID`),
CONSTRAINT `FK_tblprogramcameraxref` FOREIGN KEY (`fkProgramID`) REFERENCES `tblprogram` (`pkProgramID`)
No LEFT JOINs necessary:
SELECT DISTINCT tblprogramcameraxref.fkcameraid
FROM tblprogramcameraxref
JOIN tblprogram ON tblprogramcameraxref.fkprogramid = tblprogram.pkprogramid
AND tblprobram.fldProgramActive = 1
JOIN tblchild ON tblprogramcameraxref.fkprogramid = tblchild.fkchildprogram
AND tblchild.fldChildActive = 1
JOIN tbladultchildxref ON tblchild.pkchildid = tbladultchildxref.fkchildid
AND tbladultchildxref.fldAdultChildxRefActive = 1
WHERE tbladultchildxref.fkadultid = 675
Also, you may want to check the fkChildProgram int(1) DEFAULT NULL, in tblchild - the column it references is defined as int(11)
At this point you shouldn't really need to check if Adult is active (since that's the search criteria you started with), but if you must - just add this to the end of the join list:
JOIN tbladult ON tbladultchildxref.fkadultid = tbladult.pkadultid
AND tbladult.fldAdultActive = 1
It is a long description. If I have understood the question correctly this query should help you -
SELECT DISTINCT pcref.fkCameraID
FROM tbladult adult,
tblchild child,
tbladultchildxref acref,
tblprogram prog,
tblcamera camera,
tblprogramcameraxref pcref
WHERE adult.pkAdultID = 675
AND adult.fldAdultActive = TRUE
AND adult.pkAdultID = acref.fkAdultID
AND acref.fkChildID = child.pkChildID
AND child.fldChildActive = TRUE
AND child.fkChildProgram = prog.pkProgramID
AND prog.fldProgamActive = TRUE
AND prog.pkProgramID = pcref.fkProgramID