2012-05-28 58 views
0

今天我有一個白癡日。我相信這是相對簡單的,但我的大腦並沒有給我答案。當且僅當兄弟行不存在時返回一行

我有一個表的行是對象的類型。看起來像這樣:

id name foo bar house_id 
1  Cat  12  4  1 
2  Cat  9  4  2 
3  Dog  8  23  1 
4  Bird 9  54  1 
5  Bird 78  2  2 
6  Bird 29  32  3 

這不是我將如何選擇實現它,但它正是我正在與。對象(貓,狗和鳥,在現實生活中,它們是實際的商業用品)已被添加到表格中。當house_id 1需要貓時,貓的記錄會被放入。當house_id 3獲得狗時,狗的記錄會被放入。

我現在需要更新此表,以便類型的對象(貓,狗,鳥)對於給定的house_id的記錄。我希望通過插入select查詢的結果來實現這一點,該查詢返回每個類型的單個記錄,當且僅當沒有存在的記錄時,該類型的行中的'foo'和'bar'的最早值與給定的house_id類型。

因此,對於上面的例子中的數據,其中所述給定house_id = 3,選擇查詢將返回以下:

name foo bar house_id 
Cat  12  4  3 
Dog  8  23  3 

,我可以再插入直到表中。

基本上,如果沒有給定house_id的那個名字的行,返回每個不同名稱的第一行。

建議表示歡迎。數據庫引擎是postgres,如果有幫助。

+0

您對'foo'和'bar'的「最早」vañues的定義是什麼? – Sebas

+0

來自具有最低id的那種類型的行的值。 –

+0

那種房子或那種類型的動物? – wildplasser

回答

2
SET search_path= 'tmp'; 

DROP TABLE dogcat CASCADE; 
CREATE TABLE dogcat 
     (id serial NOT NULL 
     , zname varchar 
     , foo INTEGER 
     , bar INTEGER 
     , house_id INTEGER NOT NULL 
     , PRIMARY KEY (zname,house_id) 
     ); 
INSERT INTO dogcat(zname,foo,bar,house_id) VALUES 
    ('Cat',12,4,1) 
,('Cat',9,4,2) 
,('Dog',8,23,1) 
,('Bird',9,54,1) 
,('Bird',78,2,2) 
,('Bird',29,32,3) 
     ; 
-- Carthesian product of the {name,house_id} domains 
WITH cart AS (
     WITH beast AS (
       SELECT distinct zname AS zname 
       FROM dogcat 
       ) 
     , house AS (
       SELECT distinct house_id AS house_id 
       FROM dogcat 
       ) 
     SELECT beast.zname AS zname 
     ,house.house_id AS house_id 
     FROM beast , house 
     ) 
INSERT INTO dogcat(zname,house_id, foo,bar) 
SELECT ca.zname, ca.house_id 
     ,fb.foo, fb.bar 
FROM cart ca 
    -- find the animal with the lowes id 
JOIN dogcat fb ON fb.zname = ca.zname AND NOT EXISTS 
     (SELECT * FROM dogcat nx 
     WHERE nx.zname = fb.zname 
     AND nx.id < fb.id 
     ) 
WHERE NOT EXISTS (
     SELECT * FROM dogcat dc 
     WHERE dc.zname = ca.zname 
     AND dc.house_id = ca.house_id 
     ) 
     ; 

SELECT * FROM dogcat; 

結果:

SET 
DROP TABLE 
NOTICE: CREATE TABLE will create implicit sequence "dogcat_id_seq" for serial column "dogcat.id" 
NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index "dogcat_pkey" for table "dogcat" 
CREATE TABLE 
INSERT 0 6 
INSERT 0 3 
id | zname | foo | bar | house_id 
----+-------+-----+-----+---------- 
    1 | Cat | 12 | 4 |  1 
    2 | Cat | 9 | 4 |  2 
    3 | Dog | 8 | 23 |  1 
    4 | Bird | 9 | 54 |  1 
    5 | Bird | 78 | 2 |  2 
    6 | Bird | 29 | 32 |  3 
    7 | Cat | 12 | 4 |  3 
    8 | Dog | 8 | 23 |  2 
    9 | Dog | 8 | 23 |  3 
(9 rows) 
+0

我已經用我的解決方案完成了這項工作,但是我正在記錄下這個問題。謝謝。 –

0

由於通常情況下,我有一個問題,整個上午都在掙扎,它張貼在接下來的半小時內,堆棧溢出,並找出自己

select name, foo, bar, 3 
from table 
where id in 
(
    select min(id) from table where name not in 
    (
     select name from table where house_id = 3 
    ) 
    group by name 
); 
+0

你有house_id = 3硬編碼。 – wildplasser

+0

這足以滿足我的需求。我也不確定它能從哪裏獲得價值。 –

+0

好吧:當然是從兩個領域的凱西斯產品! – wildplasser

相關問題