Postgresql

可以用CASE來選擇要JOIN的表嗎?

  • April 13, 2022

我正在嘗試使用 CASE 表達式來選擇每行應與哪個表連接。

假設我的遊戲中有一個 item_instances 表,其中包含遊戲世界中的所有項目,其中一些項目是 item_templates 表中通用項目的千篇一律的副本,其他項目以模板開始,然後在玩家使用它們時獲得了獨特的屬性。它們現在儲存在 unique_items 表中。

因此,當我在 item_instances 表中找到一個項目的記錄時,我想查找有關它的更多資訊,並且我需要從正確的表中提取該資訊。

這是我一直在嘗試的事情,但沒有成功:

SELECT item_table, item_id, *
FROM item_instances AS ii
JOIN
CASE ii.item_table
   WHEN 0 THEN 'item_templates'
   WHEN 1 THEN 'unique_items'
   ELSE 'unique_items'
END
ON CASE = ii.item_id;

如果有語法的快速修復,我很想听聽。或者,如果這是您在概念上無法做到的事情 - 讓每一行選擇自己的連接 - 我很想獲得更深入解釋的連結。

在過去,我通過執行兩個 SELECTS 來完成這樣的操作,其中一個針對 item_templates 表,另一個針對 unique_items 表,並採用它們的 UNION。這感覺像是一種更正確且浪費更少的方法。如果不是出於某種原因與 SQL 的更深架構有關,我想了解原因。

CASE 表達式返回單個值。它不能返回標識符(例如表引用)。並且它的值不能用來代替表名

處理這種可選依賴項的典型方法是連接到每個表,並在連接條件中包含選擇表的條件。為了取回行,您將需要一個外連接,因為您不知道哪個表中會有匹配項

SELECT item_table, item_id, *
FROM item_instances AS ii
 LEFT JOIN item_templates it ON ii.item_id = it.item_id and ii.item_table = 0
 LEFT JOIN unique_items ui ON ii.item_id = ui.item_id and ii.item_table = 1

然後,您可以coalesce()在 SELECT 列表中使用,以從任一表中獲取非空值。

引用自:https://dba.stackexchange.com/questions/310837