現在のアプリケーションでは、次のタイプのクエリを実行できる必要があります。
SELECT MIN((colA, colB, colC))
FROM mytable
WHERE (colA, colB, colC) BETWEEN (200, 'B', 'C') AND (1000, 'E', 'F')
(333, 'B', 'B')
このデータを前提として、の答えを取得します。
+------+------+------+
| colA | colB | colC |
+------+------+------+
| 99 | A | A |
| 200 | A | Z |
| 200 | B | B |
| 333 | B | B |
| 333 | C | D |
| 333 | C | E |
| 333 | D | C |
| 1000 | E | G |
| 1000 | F | A |
+------+------+------+
実際のSQLでこれを実現するための最も効率的な方法は何ですか?これはおもちゃの例であり、私の実際のアプリケーションには、さまざまな列とデータ型、および数億行のテーブルがあることに注意してください。それが助けになるなら、私はMySQLを使います。これらの列には、PRIMARYまたはUNIQUEインデックスがあると想定することもできます。
ソリューションがより多くの/より少ない列に簡単に拡張できる場合、それはさらに優れています。
タプルの比較:
何人かが質問したので、これを質問に入れる必要があります。タプルは辞書式順序で並べられます。つまり、シーケンスは最初の異なる要素と同じ順序になります。たとえば、(1,2、x)<(1,2、y)はx<yと同じものを返します。
SQL(または少なくともmysql)がこれを正しく実装していることに注意してください。
mysql> select (200, 'B', 'C') < (333, 'B', 'B') and (333, 'B', 'B') < (1000, 'E', 'F');
+--------------------------------------------------------------------------+
| (200, 'B', 'C') < (333, 'B', 'B') and (333, 'B', 'B') < (1000, 'E', 'F') |
+--------------------------------------------------------------------------+
| 1 |
+--------------------------------------------------------------------------+
1 row in set (0.00 sec)
例を作成するために必要なSQLは次のとおりです。
create table mytable select 333 colA, 'B' colB, 'B' colC;
insert into mytable values (200, 'B', 'B'), (333, 'C', 'D'), (1000, 'E', 'G'),
(200, 'A', 'Z'), (1000, 'F', 'A'), (333, 'C', 'E'), (333, 'D', 'C'),
(99, 'A', 'A');
alter table mytable add unique index myindex (colA, colB, colC);
このインデックスを追加すると、テーブルが辞書式にソートされるように見えます。これは興味深いことです。これは私たちの生産システムには当てはまりません。