问题
This should be something encountered by programmers often, but I never tried to get things this way.
That is, I'll explain. Say, I need to fetch values from table Zoo like this:
@"SELECT z.predator, z.prey FROM Zoo AS z WHERE z.preyType=@carnivore"
Now I can get all the values to a List. I need to display the details of that querying in a grid. Now having got z.predator and z.prey values (which are for time sake integers, ie, their respective ids), I need to populate its meaningful values for displaying it to end user (I can't just display their ids). So now I might do something like this:
foreach (Zoo z in lstZoo)
{
Animal predator = GetFromAnimalTable(z.Predator)
Animal prey = GetFromAnimalTable(z.Prey)
}
This can make the program slower. Can I query all the details in one go? Something like this:
SELECT (SELECT * FROM ANIMAL WHERE id=z.predator),
(SELECT * FROM ANIMAL WHERE id=z.prey)
FROM Zoo AS z WHERE z.preyType=@carnivore
Provided I can read the values to a new bigger object? Or is this considered a bad practice?
UPDATE: Is it a standard practice to do this? Or is it recommended to individually populate as I stated first?
UPDATE 2: I seem to have made a terrible mistake of not posting the query exactly as I needed. I thought I could tweak the answers from here to meet my requirement, alas no with the parenthesis construction of Access queries.
Here is how my actual query would be:
SELECT z.predator, p.lifeSpan, z.prey
FROM Zoo AS z
INNER JOIN Plants AS p ON p.parent_id=z.id
WHERE z.preyType=@carnivore
Actually I had an INNER JOIN query already with another table. Now I need to get (SELECT) values of z.predator (and its corresponding values from Animals table), p.lifeSpan, z.prey (and its corresponding values from Animal table) meeting the INNER JOIN and WHERE condition.
A pseudo code would look like this:
SELECT (SELECT * FROM ANIMAL WHERE id=z.predator), p.lifeSpan, (SELECT * FROM ANIMAL WHERE id=z.prey)
FROM Zoo AS z INNER JOIN Plants AS p ON p.parent_id=z.id
WHERE z.preyType=@carnivore
It should be pretty easy to extend my requirement from the answers here, but no success till now. I tried:
SELECT a1.*, p.lifeSpan, a2.*
FROM Zoo AS z
INNER JOIN Plants AS p ON p.parent_id=z.id
INNER JOIN Animal AS a1 ON (a1.id=z.predator)
INNER JOIN Animal AS a2 ON (a2.id=z.prey)
WHERE z.preyType=@carnivore
And many variants of this with and without brackets. How can the above query be properly structured?
回答1:
It seems this your latest query attempt:
SELECT a1.*, p.lifeSpan, a2.*
FROM Zoo AS z
INNER JOIN Plants AS p ON p.parent_id=z.id
INNER JOIN Animal AS a1 ON (a1.id=z.predator)
INNER JOIN Animal AS a2 ON (a2.id=z.prey)";
WHERE z.preyType=@carnivore
Discard the semicolon from inside the statement. Also discard the double quote.
Just to simplify the SQL, exclude the WHERE clause for now.
Then you should be in a better position to address the issue of parentheses which Access' db engine requires for multiple joins.
SELECT a1.*, p.lifeSpan, a2.*
FROM
((Zoo AS z
INNER JOIN Plants AS p ON p.parent_id=z.id)
INNER JOIN Animal AS a1 ON a1.id=z.predator)
INNER JOIN Animal AS a2 ON a2.id=z.prey
Notice I discarded those parentheses which enclosed the ON expressions. Simple ON expressions don't require them. If you had a compound expression for ON, then you would need parentheses like this:
ON (p.parent_id=z.id AND p.foo = z.bar)
The sample query I suggested looks correct to me. (If it works for you, add your WHERE clause back again.) However, I don't pay close attention to parentheses placement because I use Access' query designer to set up joins ... and it adds the parentheses the db engine requires.
I urge you to do the same. If you're using an Access db from Dot.Net without having a copy of Access installed, you really should get a copy. Trying to use a database without that database's native development tools is an unreasonable challenge ... somewhat like trying to type while wearing mittens.
回答2:
SELECT pred.col1 AS PredCol1, ..., pred.colx AS PredColx,
prey.col1 AS PreyCol1, ..., prey.colx AS PreyColx
FROM Zoo z
INNER JOIN Animal pred
ON z.predator = pred.id
INNER JOIN Animal prey
ON z.prey = prey.id
WHERE z.preyType = @carnivore
Alternatively, you might want something like this instead.
SELECT 'Predator' AS AnimalType, pred.*
FROM Zoo z
INNER JOIN Animal pred
ON z.predator = pred.id
WHERE z.preyType = @carnivore
UNION ALL
SELECT 'Prey' AS AnimalType, prey.*
FROM Zoo z
INNER JOIN Animal prey
ON z.prey = prey.id
WHERE z.preyType = @carnivore
回答3:
Try with Joining the tables
SELECT aPrey.Name as PreyName, aPredatior.Name as PredatorName
FROM Zoo AS z
LEFT JOIN Animal AS aPrey On aPrey.id= z.prey
LEFT JOIN Animal AS aPredatior On aPredatior.id= z.predator
WHERE z.preyType=@carnivore
来源:https://stackoverflow.com/questions/8842729/how-do-i-select-populate-two-objects-from-two-tables-with-a-single-query