2014-02-20 123 views
1

假設我有這些表:SQL訂購一個複雜的查詢

items,存儲項目。

CREATE TABLE items 
(
    id serial NOT NULL, 
    name character varying(255), 
    rarity character varying(255), 
    created_at timestamp without time zone, 
    updated_at timestamp without time zone, 
    CONSTRAINT items_pkey PRIMARY KEY (id) 
) 

item_modifiers,管理項目和改性劑

CREATE TABLE item_modifiers 
(
    id serial NOT NULL, 
    item_id integer, 
    modifier_id integer, 
    primary_value integer, 
    secondary_value integer, 
    CONSTRAINT item_modifiers_pkey PRIMARY KEY (id) 
) 

modifiers之間的許多一對多的關係,它包含了所有可能的項目修飾符

CREATE TABLE modifiers 
(
    id serial NOT NULL, 
    name character varying(255), 
    CONSTRAINT explicit_mods_pkey PRIMARY KEY (id) 
) 

現在假設我有一個複雜查詢。我想找到ID爲1

有ID爲1和2修飾符的所有項目,由改性劑的PRIMARY_VALUE下令我曾嘗試此查詢

SELECT "items".*, item_modifiers.primary_value FROM "items" 
INNER JOIN item_modifiers ON item_modifiers.item_id = items.id 
AND ((item_modifiers.modifier_id = 1) 
OR (item_modifiers.modifier_id = 2)) 
GROUP BY items.id, item_modifiers.primary_value 
HAVING 
COUNT(item_modifiers.id) = 2 
ORDER BY item_modifiers.primary_value DESC 

但它返回一個空的結果集。但是,當我不按主要價值分組時,它確實存在,但我無法訂購它。我一直堅持這個很長時間,所以任何幫助,非常感謝。

編輯我已經建立了一個SQL小提琴證明 http://sqlfiddle.com/#!15/30887/1

回答

1

你不必參加與item_modifiers與modifier_id 2,你只希望它能保證這樣的記錄存在:

SELECT items.*, item_modifiers.primary_value 
FROM items 
INNER JOIN item_modifiers ON item_modifiers.item_id = items.id AND item_modifiers.modifier_id = 1 
WHERE EXISTS 
(
    SELECT * 
    FROM item_modifiers 
    WHERE item_modifiers.item_id = items.id AND item_modifiers.modifier_id = 2 
) 
ORDER BY item_modifiers.primary_value DESC; 

她e是你的SQL小提琴:http://sqlfiddle.com/#!15/30887/9

+1

下面是解決這個問題的另一種方法,只對你的陳述稍作修改:http://sqlfiddle.com/#!15/30887/17。 –

+0

這幾乎就是這樣,除了現在(在我的生產數據庫中)一些primary_values是空白的,它們出現在頂部。有沒有辦法讓空白值在底部使用CASE,然後在第二個sqlfiddle中出現? –

+1

由於primary_value是一個整數,所以空值意味着NULL。您可以使用ORDER BY .... DESC NULLS LAST將它們移動到結果列表的末尾。 –

0

這是你在找什麼:

SELECT "items".*, 
     item_modifiers.primary_value 
FROM "items" 
     INNER JOIN item_modifiers 
       ON item_modifiers.item_id = items.id 
        AND ((item_modifiers.modifier_id = 1) 
         OR (item_modifiers.modifier_id = 2)) 
ORDER BY item_modifiers.primary_value DESC;