哪些数据库可以运行以下SQL?

时间:2011-10-21 23:38:58

标签: mysql sql database

我构建了一个查询,我想知道它是否适用于MySQL以外的任何数据库。我从来没有真正使用过其他数据库,所以我对差异并不是很了解。

UPDATE `locks` AS `l1`
  CROSS JOIN (SELECT SUM(`value`) AS `sum` FROM `locks`
              WHERE `key` IN ("key3","key2")) AS `l2`
SET `l1`.`value` = `l1`.`value` + 1
WHERE `l1`.`key` = "key1" AND (`l2`.`sum` < 1);

以下是我所依赖的具体功能(我能想到它们):

  1. 更新查询。
  2. 加入更新查询。
  3. 在非显式分组查询中聚合函数。
  4. 在哪里......状况良好。
  5. 我确信人们会好奇这是做什么的,这也可能包括可能无处不在的数据库功能。这是使用数据库进行互斥的实现,用于Web应用程序。在我的情况下,我需要它,因为某些用户操作导致表被删除并使用不同的列重新创建,我想避免错误,如果应用程序的其他部分尝试插入数据。因此,实施专门用于解决the readers-writers problem

    此查询假定存在一个包含两个字段的表lockskey(varchar)和value(int)。它进一步假设该表包含一行key =“key1”。然后它尝试为“key1”增加value。只有对于列表key中的每个("key2","key3"),关联的value为0(l2的WHERE条件为假定value的近似值时才会这样做永远不会消极)。因此,如果满足某些条件,则该查询仅“获得锁定”,可能是以原子方式。然后,应用程序检查它是否通过查询的返回值收到锁定,该返回值可能表示受影响的行数。当且仅当没有行受到影响时,应用程序才会收到锁定。

    因此,以下是查询本身无法辨别的附加条件:

    1. 假设在多线程环境中,此查询的副本永远不会与另一个副本交错。
    2. 处理查询时必须返回是否有任何值受到影响。
    3. 作为辅助请求,我将非常感谢“标准SQL”上的所有资源。我听说过它但从来没有找到任何类型的定义,当MySQL文档说“这个功能是标准SQL的扩展”时,我觉得我错过了很多东西。

      根据回复,此查询应在所有系统中更好地运行:

      UPDATE locks AS l1
        CROSS JOIN (SELECT SUM(val) AS others FROM locks
                    WHERE keyname IN ('key3','key2')) AS l2
      SET l1.val = l1.val + 1
      WHERE l1.keyname = 'key1' AND (l2.others < 1);
      

      因为好的答案而为每个人提供支持。标记的答案旨在直接回答我的问题,即使只针对另一个DBMS,即使可能有更好的解决方案来解决我的特定问题(甚至是跨平台SQL的问题)。

3 个答案:

答案 0 :(得分:6)

此确切语法仅适用于MySQL

这个构造是一个丑陋的解决方法:

UPDATE  locks
SET     value = 1
WHERE   key = 'key1'
        AND NOT EXISTS
        (
        SELECT  NULL
        FROM    locks li
        WHERE   li.key IN ('key2', 'key3')
                AND li.value > 0
        )

适用于除MySQL之外的所有系统,因为后者不允许UPDATEDELETE语句中的目标表上的子查询。

答案 1 :(得分:3)

对于PostgreSQL

  

1)更新查询。

无法想象没有UPDATE的RDBMS。 (?)

  

2)加入更新查询。

在PostgreSQL中,您将包含FROM from_list的附加表。

  

3)非分组查询中的聚合函数。

PostgreSQL中不可能。使用子查询,CTE或Window函数。
但您的查询 已分组。 GROUP BY子句没有拼写出来。这也适用于PostgreSQL。

  

即使存在,HAVING也会将查询转换为分组查询   没有GROUP BY子句。这和发生时的情况相同   查询包含聚合函数但不包含GROUP BY子句。

(Quote from the manual)。

  

4)WHERE ... IN条件

适用于我所知道的任何RDBMS。

  

“附加条件”:假设在多线程环境中,此查询的副本永远不会与另一个副本交错。

PostgreSQL的multiversion model MVCC(多版本并发控制)在处理并发性方面优于MySQL。然而,在这方面,大多数RDBMS都优于MySQL。

  

处理查询时必须返回是否有任何值受到影响。

Postgres这样做,大多数RDBMS都这样做。

此外,此查询不会在PostgreSQL中运行,因为:

  • 没有identifiers有反引号(那是MySQL俚语)。
  • 值必须是单引号,而不是双引号。

请参阅list of reserved words in Postgres and SQL standards 一个combined list for various RDBMS

答案 2 :(得分:2)

这只能在mysql中使用,因为你使用的是“`”分隔符,它只是特定于mysql的。

如果用更“标准”的分隔符替换分隔符怎么办:那么它可能适用于所有现代DBMS(postgres,sql server,oracle),但我绝不会为所有人编写一般查询 - 我最好写一个每个使用过的(或可能使用的)DBMS的特定查询,以使用其特定的语言方言来获得最佳性能和查询可读性。

如果“作为辅助请求,我会很感激”标准SQL“上的任何资源。”“看看http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt