2011-09-19 67 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“;