Как (SELECT) заполнить два объекта из двух таблиц одним запросом? - PullRequest
1 голос
/ 13 января 2012

Это должно часто встречаться программистам, но я никогда не пытался понять это таким образом.

То есть я объясню.Скажем, мне нужно получить значения из таблицы Zoo следующим образом:

 @"SELECT z.predator, z.prey FROM Zoo AS z WHERE z.preyType=@carnivore"

Теперь я могу получить все значения в список.Мне нужно отобразить детали этого запроса в сетке.Теперь, получив значения z.predator и z.prey (для целых чисел, т. Е. Их соответствующих идентификаторов), мне нужно заполнить их значимые значения для отображения конечному пользователю (я не могу просто отобразить их идентификаторы).Теперь я могу сделать что-то вроде этого:

 foreach (Zoo z in lstZoo)
 {
       Animal predator = GetFromAnimalTable(z.Predator)
       Animal prey = GetFromAnimalTable(z.Prey)
 }

Это может замедлить работу программы.Могу ли я запросить все детали за один раз?Примерно так:

   SELECT (SELECT * FROM ANIMAL WHERE id=z.predator), 
          (SELECT * FROM ANIMAL WHERE id=z.prey) 
   FROM Zoo AS z WHERE z.preyType=@carnivore

При условии, что я могу прочитать значения для нового большего объекта?Или это считается плохой практикой?

ОБНОВЛЕНИЕ: Это стандартная практика для этого?Или рекомендуется заполнять по отдельности, как я указывал вначале?

ОБНОВЛЕНИЕ 2 : Кажется, я совершил ужасную ошибку, отправив запрос не так, как мне было нужно.Я думал, что смогу откорректировать ответы отсюда, чтобы удовлетворить мои требования, увы нет с конструкцией скобок запросов Access.

Вот как мой фактический запрос будет:

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

На самом деле яуже был запрос INNER JOIN с другой таблицей.Теперь мне нужно получить (SELECT) значения z.predator (и соответствующих значений из таблицы Animals), p.lifeSpan, z.prey (и соответствующих значений из таблицы Animal), соответствующих условиям INNER JOIN и WHERE.

Псевдокод будет выглядеть так:

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

Было бы довольно легко расширить мои требования из ответов здесь, но безуспешно до сих пор.Я пробовал:

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

И много вариантов этого с и без скобок.Как правильно структурировать приведенный выше запрос?

Ответы [ 3 ]

4 голосов
/ 13 января 2012
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

В качестве альтернативы вы можете захотеть что-то вроде этого.

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
2 голосов
/ 13 января 2012

Кажется, это ваша последняя попытка запроса:

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

Откажитесь от точки с запятой внутри оператора.Также отбросьте двойную кавычку.

Просто, чтобы упростить SQL, пока исключите предложение WHERE.

Тогда вы должны быть в лучшем положении для решения вопроса о круглых скобках, которые требуются в db-модуле Access для множественных объединений.

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

Примечание.Простые выражения ON не требуют их.Если у вас есть составное выражение для ON, то вам понадобятся круглые скобки, подобные этому:

ON (p.parent_id=z.id AND p.foo = z.bar)

Пример запроса, который я предложил, выглядит для меня корректным.(Если это работает для вас, снова добавьте предложение WHERE.) Однако я не обращаю пристального внимания на размещение скобок, потому что я использую конструктор запросов Access для настройки объединений ... и он добавляет скобки, необходимые для механизма обработки данных.,

Я призываю вас сделать то же самое.Если вы используете базу данных Access из Dot.Net без установленной копии Access, вы действительно должны получить копию.Попытка использовать базу данных без встроенных средств разработки этой базы является неоправданной проблемой ... чем-то вроде попытки печатать, надев варежки.

1 голос
/ 13 января 2012

Попробуйте присоединиться к столам

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
...