SQL:如何正确检查记录是否存在

发布于 2024-10-04 10:32:32 字数 201 浏览 3 评论 0原文

在阅读一些与 SQL 调优相关的文档时,我发现了这一点:

SELECT COUNT(*)

  • 计算行数。
  • 通常被不适当地用于验证记录的存在。

SELECT COUNT(*) 真的那么糟糕吗?

验证记录是否存在的正确方法是什么?

While reading some SQL Tuning-related documentation, I found this:

SELECT COUNT(*) :

  • Counts the number of rows.
  • Often is improperly used to verify the existence of a record.

Is SELECT COUNT(*) really that bad?

What's the proper way to verify the existence of a record?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

天荒地未老 2024-10-11 10:32:32

最好使用以下任一选项:

-- Method 1.
SELECT 1
FROM table_name
WHERE unique_key = value;

-- Method 2.
SELECT COUNT(1)
FROM table_name
WHERE unique_key = value;

第一个选项应该没有结果或一个结果,第二个计数应该为零或一。

您使用的文档有多旧?尽管您读过很好的建议,但最近 RDBMS 中的大多数查询优化器都会优化 SELECT COUNT(*),因此虽然理论上(和旧数据库)存在差异,但您不应该注意到任何差异在实践中。

It's better to use either of the following:

-- Method 1.
SELECT 1
FROM table_name
WHERE unique_key = value;

-- Method 2.
SELECT COUNT(1)
FROM table_name
WHERE unique_key = value;

The first alternative should give you no result or one result, the second count should be zero or one.

How old is the documentation you're using? Although you've read good advice, most query optimizers in recent RDBMS's optimize SELECT COUNT(*) anyway, so while there is a difference in theory (and older databases), you shouldn't notice any difference in practice.

萌辣 2024-10-11 10:32:32

我宁愿根本不使用 Count 函数:

IF [NOT] EXISTS ( SELECT 1 FROM MyTable WHERE ... )
     <do smth>

例如,如果您想在将用户插入数据库之前检查用户是否存在,则查询可以如下所示:

IF NOT EXISTS ( SELECT 1 FROM Users WHERE FirstName = 'John' AND LastName = 'Smith' )
BEGIN
    INSERT INTO Users (FirstName, LastName) VALUES ('John', 'Smith')
END

I would prefer not use Count function at all:

IF [NOT] EXISTS ( SELECT 1 FROM MyTable WHERE ... )
     <do smth>

For example if you want to check if user exists before inserting it into the database the query can look like this:

IF NOT EXISTS ( SELECT 1 FROM Users WHERE FirstName = 'John' AND LastName = 'Smith' )
BEGIN
    INSERT INTO Users (FirstName, LastName) VALUES ('John', 'Smith')
END
城歌 2024-10-11 10:32:32

可以使用:

SELECT 1 FROM MyTable WHERE <MyCondition>

如果没有符合条件的记录,则结果记录集为空。

You can use:

SELECT 1 FROM MyTable WHERE <MyCondition>

If there is no record matching the condition, the resulted recordset is empty.

脱离于你 2024-10-11 10:32:32

您可以使用:

SELECT 1 FROM MyTable WHERE... LIMIT 1

使用 select 1 来防止检查不必要的字段。

使用LIMIT 1 来防止检查不必要的行。

You can use:

SELECT 1 FROM MyTable WHERE... LIMIT 1

Use select 1 to prevent the checking of unnecessary fields.

Use LIMIT 1 to prevent the checking of unnecessary rows.

你曾走过我的故事 2024-10-11 10:32:32
SELECT COUNT(1) FROM MyTable WHERE ...

将循环遍历所有记录。这就是使用记录存在不好的原因。

我会使用

SELECT TOP 1 * FROM MyTable WHERE ...

After find 1 record, 它将终止循环。

SELECT COUNT(1) FROM MyTable WHERE ...

will loop thru all the records. This is the reason it is bad to use for record existence.

I would use

SELECT TOP 1 * FROM MyTable WHERE ...

After finding 1 record, it will terminate the loop.

走过海棠暮 2024-10-11 10:32:32

其他答案都很好,但添加 LIMIT 1 (或 等效,以防止检查不必要的行。

The other answers are quite good, but it would also be useful to add LIMIT 1 (or the equivalent, to prevent the checking of unnecessary rows.

瞳孔里扚悲伤 2024-10-11 10:32:32

您可以使用:

SELECT COUNT(1) FROM MyTable WHERE ... 

WHERE [NOT] EXISTS 
( SELECT 1 FROM MyTable WHERE ... )

这将比 SELECT * 更有效,因为您只需为每行而不是所有字段选择值 1。

COUNT(*) 和 COUNT(column name) 之间还有一个细微的区别:

  • COUNT(*) 将计算所有行,包括 null
  • COUNT(column name) 将仅计算列名出现非空

You can use:

SELECT COUNT(1) FROM MyTable WHERE ... 

or

WHERE [NOT] EXISTS 
( SELECT 1 FROM MyTable WHERE ... )

This will be more efficient than SELECT * since you're simply selecting the value 1 for each row, rather than all the fields.

There's also a subtle difference between COUNT(*) and COUNT(column name):

  • COUNT(*) will count all rows, including nulls
  • COUNT(column name) will only count non null occurrences of column name
雨轻弹 2024-10-11 10:32:32

其他选项:

SELECT CASE
    WHEN EXISTS (
        SELECT 1
        FROM [MyTable] AS [MyRecord])
    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END

Other option:

SELECT CASE
    WHEN EXISTS (
        SELECT 1
        FROM [MyTable] AS [MyRecord])
    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END
饮惑 2024-10-11 10:32:32

我正在使用这种方式:

IF (EXISTS (SELECT TOP 1 FROM Users WHERE FirstName = 'John'), 1, 0) AS DoesJohnExist

I'm using this way:

IF (EXISTS (SELECT TOP 1 FROM Users WHERE FirstName = 'John'), 1, 0) AS DoesJohnExist
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文