4

私が取り組んでいたかなり複雑な SQL クエリにより、(ANSI) SQL の制限について考えさせられました。

任意の順序に関して最大​​または最小のレコードを取得する方法はありますか?

言い換えると:

次のようなクエリがあるとします。

SELECT * FROM mytable WHERE <various conditions> ORDER BY <order clause>

最初の行のみを返すクエリを作成することは可能ですか (おそらく order 句を別のものに変換することによって)?

LIMIT (MySQL) / ROWNUM (Oracle) などを使用してこれを実行できることは知っていますが、それは標準 SQL ではありません。

また、サブクエリで関心のある最大/最小値を取得し (MIN()/MAX() を使用)、その結果をメインの SELECT の基準として使用することでこれを実行できることも知っています。

SELECT * FROM mytable WHERE <various conditions> AND myMaxColumn=(
  SELECT MAX(myMaxColumn) FROM mytable WHERE <various conditions>
)

しかし、それは単一の列で並べ替えたい場合にのみ機能します。これを複数の列に一般化する方法はありません(上記のソリューションをネストする以外に、n列で並べ替えると2 ^ n SELECTになることを意味します)。

複数の副選択をネストするよりも、標準 SQL でより良い方法はありますか?

関連する質問は、SQL クエリを作成して最新のレコードを取得するで尋ねられます。ただし、そこにある回答は、LIMIT と友人を使用するか、上記で説明したように MAX() でサブクエリを使用することを示唆していますが、どちらも私の質問に対する解決策ではありません。

4

2 に答える 2

10

SQL:2003ウィンドウ関数の概念を定義します。そのうちの1つは次のとおりです。

SELECT  *
FROM    (
        SELECT  *, ROW_NUMBER() OVER (ORDER BY col1, col2, col3) AS rn
        FROM    mytable
        ) q
WHERE   rn = 1

この最初のレコードが返されます。

今のところ、それはによってサポートされてSQL ServerおりOracle、以来Jul 01, 2009PostgreSQL 8.4

ただし、ROW_NUMBER()inOracleは、レコードを制限するネイティブの方法(つまりROWNUM)よりも効率が低いことに注意してください。

パフォーマンスの比較については、私のブログのこの記事を参照してください。

SQL:2008これを行うための別の句を提供します:

SELECT  *
FROM    mytable
ORDER BY
        col1, col2, col3
FETCH FIRST 1 ROW ONLY

DB2、ただし、現時点では、この正確な構文は()でのみサポートされていますAFAIK

于 2009-07-13T12:05:48.853 に答える
8

私があなたを正しく理解していれば、 ANSISQL2003標準の一部として定義されている結果セットを分割できるOVER句を探していると思います。

RDBMSプラットフォーム全体で一貫して実装されているわけではありません。

于 2009-07-13T12:06:14.390 に答える