2011-09-19 65 views
94

我有一堆行需要插入表中,但這些插入始終是分批進行的。所以我想檢查一下表中是否有單行存在,因爲我知道它們都被插入了。最快的檢查PostgreSQL中是否存在行

所以它不是主鍵檢查,但不應該太重要。我想只檢查單排所以count(*)可能不太好,所以我想它的東西就像exists

但是因爲我對PostgreSQL相當陌生,所以我寧願問問知道的人。

我的批處理包含以下結構上按行:

userid | rightid | remaining_count 

所以,如果表中包含提供userid這意味着他們都是目前有任何行。

+0

您想查看該表是否有任何行或批次中的任何行? – JNK

+0

我的批次中的任何行是。他們都有同樣的領域生病編輯一點。 –

+0

請說明你的問題。你想添加一批記錄,全部還是全無?伯爵有什麼特別之處? (順便說一句保留字,作爲列名不切實際) – wildplasser

回答

174

使用EXISTS關鍵字爲TRUE/FALSE返回:

select exists(select 1 from contact where id=12) 
+9

此擴展,您可以命名返回的列以便於參考。例如'select exists(select from contact where id = 12)AS「exists」' – Rowan

+3

這樣比較好,因爲它總是會返回一個值(true或false),而不是有時無(取決於您的編程語言)擴大你的期望。 – isaaclw

+1

我有Seq掃描使用這種方法。我做錯了什麼? – FiftiN

0
SELECT 1 FROM user_right where userid = ? LIMIT 1 

如果您的結果集包含一行,那麼您不必插入。否則插入您的記錄。

+0

如果包含100行,它將返回100行,你認爲那很好? –

+0

您可以將其限制爲1行。應該表現更好。查看@aix編輯的答案。 –

0
select true from tablename where condition limit 1; 

我認爲,這是Postgres使用檢查外鍵查詢。

在你的情況,你可以這樣做在一個走得:

insert into yourtable select $userid, $rightid, $count where not (select true from yourtable where userid = $userid limit 1); 
23

如何簡單:

select 1 from tbl where userid = 123 limit 1; 

其中123是,你要插入批次的用戶ID 。

上述查詢將返回空集或單行,具體取決於是否有給定用戶標識的記錄。

如果結果太慢,您可以考慮在tbl.userid上創建索引。

如果從批量甚至單排表中存在,在這種情況下我 不必插入我行,因爲我確信他們都是 插入。

即使您的程序在中間批次中斷,我仍建議您確保正確管理數據庫事務(即整個批處理在單個事務中被插入)。

+0

當然,即時通訊使用交易 –

+11

它可能在編程上更容易「從select(select ... limit 1)中選擇count(\ *)」,因爲它總是會返回一個count爲(\ *)的行0或1. –

+0

@DavidAldridge計數(*)仍然意味着所有的行都必須被讀取,而限制1停在第一條記錄處並返回 – Imraan

8
INSERT INTO target(userid, rightid, count) 
    SELECT userid, rightid, count 
    FROM batch 
    WHERE NOT EXISTS (
    SELECT * FROM target t2, batch b2 
    WHERE t2.userid = b2.userid 
    -- ... other keyfields ... 
    )  
    ; 

順便說一句:如果你想整批在重複的情況下失敗,則(給定一個主鍵約束)

INSERT INTO target(userid, rightid, count) 
SELECT userid, rightid, count 
FROM batch 
    ; 

將不正是你想要的東西:要麼成功,否則失敗。

+0

這將檢查每一行。他想要做一次檢查。 – JNK

+0

不,它會執行一次檢查。子查詢不相關。一旦找到一對配對,它就會退出。 – wildplasser

+0

你是對的,我認爲它涉及到外部查詢。 +1給你 – JNK

0

如果你對服務表現,可能是你可以在一個函數中使用「執行」就像這樣:

PERFORM 1 FROM skytf.test_2 WHERE id=i LIMIT 1; 
    IF FOUND THEN 
     RAISE NOTICE ' found record id=%', i; 
    ELSE 
     RAISE NOTICE ' not found record id=%', i; 
END IF; 
+0

不適用於我:我得到一個語法錯誤附近執行 – Simon

+0

這是pl/pgsql,而不是SQL,因此如果試圖運行它作爲SQL「PERFORM」的語法錯誤 –

0

憑經驗

選擇存在( 從XX選擇true其中xx )作爲「請問1個+ 1加s高達2「;