這裏有兩個不同的解決方案:(注:我叫枚舉場「package_t YPE「)
第一溶液(通過IF()函數):
select
i.location,
if(ps.id is not null, ps.id, pg.id) as package_id
from
(select distinct location from Items) i
inner join
(select i.location, p.id
from Items i
inner join Packages p on (i.package_id = p.id and p.package_type = 'general')
) pg on (i.location = pg.location)
left join
(select i.location, p.id
from Items i
inner join Packages p on (i.package_id = p.id and p.package_type = 'special')
) ps on (i.location = ps.location)
該溶液基本上需要的位置,並將其加入到封裝與一般(其被假定爲存在;因此inner join
)和特殊包裝(這是可選的;因此left join
)。它創造的記錄,如本:
location | general-package | [special-package]
它然後使用MySQL IF
功能的第一次嘗試選擇特殊包的ID,然後回落到普通包的ID。
第二溶液(通過枚舉的鑄造到整數):
select i.location, p.id
from
(select i.location, max(cast(package_type as unsigned)) as package_type
from Items i
left join Packages p on (i.package_id = p.id)
group by location
) i
inner join
(select i.location, p.id, p.package_type
from Items i
inner join Packages p on (i.package_id = p.id)
) p on (i.location = p.location and i.package_type = p.package_type)
將該溶液利用了Enum也被存儲爲整數的事實。它將枚舉轉換爲整數。 special
在這種情況下將返回2
和general
將返回1
。因爲在這種情況下這些特殊值保證高於一般值(即2> 1),所以我們可以使用MAX
聚合函數。現在我們基本上有一張地點表和他們的「推薦套餐」(如果存在的話,一般情況下是特殊的)。我們只需將它與預期的包類型一起加入到普通查詢中,並返回正確的結果。
聲明:我不確定這些方法的效率,所以你可能想自己測試一下。
如果你正在尋找要麼重新設計表或進行非規範化以提高效率,我覺得這樣的設計可能更適合:
GeneralPackages table
id, name
1, General Package 1
SpecialPackages table
id, name
1, Special Package 1
2, Special Package 2
Items table
id, general_package_id, special_package_id, location
1, 1, NULL, America
2, 1, 2, Europe
的好處是,它更容易執行
- 一個位置必須始終有一個大致的包(Items.general_package_id可以被定義爲NOT NULL)
:在數據庫級別的幾個規則
- 一個位置必須只有一個通用包(在域中添加它,而不是連接保證只有一個指定)
- 一個位置最多隻能包含一個特殊包(將其添加到一個字段中而不是一個連接保證只有一個指定)
- Items.general_package_id = GeneralPackages.id上的外鍵將保證該列只包含「普通」的有效包。
- 對於special_package_id可以做同樣的事情。
缺點是您每次使用舊查詢時都可能需要使用UNION ALL。
應該指出的是:「沒有這樣的假設,特殊的包裝有更高的IDS,我只是爲了清晰起見而製作了更小的表格。」 - 理解 – Senseful 2010-05-05 21:29:39
@Eagle:我不明白爲什麼它會導致混淆,但澄清此外,軟件包表有超過'n'條目。每個條目都有一個ID和一個類型。類型可以是「一般」或「特殊」。 – understack 2010-05-05 21:45:15
對不起,我誤解了這個問題。我想我現在明白了。我感到困惑與枚舉認爲它可能包含超過2個不同的值。 – Senseful 2010-05-05 22:31:27