簡體   English   中英

如何通過單個查詢從兩個表中填充兩個對象?

[英]How do I (SELECT) populate two objects from two tables with a single query?

這應該是程序員經常遇到的問題,但是我從來沒有嘗試過用這種方式來解決問題。

也就是說,我會解釋。 說,我需要像這樣從表Zoo獲取值:

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

現在,我可以將所有值都添加到列表中。 我需要在網格中顯示該查詢的詳細信息。 現在已經有了z.predator和z.prey值(它們是時間上的整數,即它們各自的ID),我需要填充其有意義的值以將其顯示給最終用戶(我不能只顯示其ID)。 所以現在我可以做這樣的事情:

 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)滿足INNER JOIN和WHERE條件的z.predator值(及其來自Animals表的對應值),p.lifeSpan,z.prey(及其對應的Animal表的值)。

偽代碼如下所示:

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

以及帶有和不帶有括號的許多變體。 如何正確構造以上查詢?

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

看來這是您最近的查詢嘗試:

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子句。

然后,您應該可以更好地解決Access的db引擎多次聯接所需的括號問題。

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的復合表達式,則需要這樣的括號:

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

我建議的示例查詢對我來說看起來是正確的。 (如果它對您有用,請再次添加您的WHERE子句。)但是,由於我使用Access的查詢設計器來建立聯接,因此我並沒有特別注意括號的位置...並且它添加了db引擎所需的括號。 。

我敦促您也這樣做。 如果您使用的是來自Dot.Net的Access數據庫,而未安裝Access副本,那么您確實應該獲得一個副本。 嘗試在沒有該數據庫的本機開發工具的情況下使用數據庫是一個不合理的挑戰……有點像在戴手套時嘗試鍵入。

嘗試加入表格

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM