How do I (SELECT) populate two objects from two ta

2019-03-02 12:41发布

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?

3条回答
闹够了就滚
2楼-- · 2019-03-02 13:12

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.

查看更多
甜甜的少女心
3楼-- · 2019-03-02 13:13

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
查看更多
来,给爷笑一个
4楼-- · 2019-03-02 13:14
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
查看更多
登录 后发表回答