sql >> データベース >  >> RDS >> PostgreSQL

psqlで、CTEを使用してSelectクエリのループを実行し、読み取り専用データベースで実行した場合に表示される出力を取得する方法は?

    私がこの権利を解読する場合、基本的には、降順のIDに応じた行番号がアドレスに表示されるすべての人を選択する必要があります。最終的な結果は、これらの行番号の一部に限定する必要があります。

    そうすれば、その面倒な LIMITを使用する必要はありません。 /オフセット まったく構築します。 row_number()を使用するだけです。 ウィンドウ関数。

    行番号をフィルタリングするには、 INを使用するだけです。 。ここで必要なものに応じて、特に数字が連続していない場合は、リテラルのリストを使用できます。または、 generate_series()を使用できます 連続番号のリストを生成します。もちろん、数値が別のテーブルに格納されている場合は、サブクエリを使用することもできます。

    次のようなリテラルのリストを使用します。

    SELECT pn.personid,
           pn.lastname,
           pn.firstname,
           pn.address,
           pn.city
           FROM (SELECT p.personid,
                        p.lastname,
                        p.firstname,
                        p.address,
                        p.city,
                        row_number() OVER (ORDER BY p.personid DESC) n
                        FROM persons p) pn
           WHERE pn.address LIKE concat('%', pn.n, '%')
                 AND pn.n IN (1, 2, 4);
    

    generate_series()を使用する場合 例は次のとおりです。

    SELECT pn.personid,
           pn.lastname,
           pn.firstname,
           pn.address,
           pn.city
           FROM (SELECT p.personid,
                        p.lastname,
                        p.firstname,
                        p.address,
                        p.city,
                        row_number() OVER (ORDER BY p.personid DESC) n
                        FROM persons p) pn
           WHERE pn.address LIKE concat('%', pn.n, '%')
                 AND pn.n IN (SELECT s.n
                                     FROM generate_series(1, 3) s (n));
                                 
    

    また、別のテーブルのサブクエリを次のように使用できます。

    SELECT pn.personid,
           pn.lastname,
           pn.firstname,
           pn.address,
           pn.city
           FROM (SELECT p.personid,
                        p.lastname,
                        p.firstname,
                        p.address,
                        p.city,
                        row_number() OVER (ORDER BY p.personid DESC) n
                        FROM persons p) pn
           WHERE pn.address LIKE concat('%', pn.n, '%')
                 AND pn.n IN (SELECT t.nmuloc
                                     FROM elbat t);
    

    数値のセットが大きい場合は、 INNER JOINの使用を検討することもできます。 INの代わりに数字に 。

    generate_series()の使用 :

    SELECT pn.personid,
           pn.lastname,
           pn.firstname,
           pn.address,
           pn.city
           FROM (SELECT p.personid,
                        p.lastname,
                        p.firstname,
                        p.address,
                        p.city,
                        row_number() OVER (ORDER BY p.personid DESC) n
                        FROM persons p) pn
                INNER JOIN generate_series(1, 1000000) s (n)
                           ON s.n = pn.n
           WHERE pn.address LIKE concat('%', pn.n, '%');
    

    または、番号が別のテーブルにある場合:

    SELECT pn.personid,
           pn.lastname,
           pn.firstname,
           pn.address,
           pn.city
           FROM (SELECT p.personid,
                        p.lastname,
                        p.firstname,
                        p.address,
                        p.city,
                        row_number() OVER (ORDER BY p.personid DESC) n
                        FROM persons p) pn
                INNER JOIN elbat t
                           ON t.nmuloc = pn.n
           WHERE pn.address LIKE concat('%', pn.n, '%');
    

    また、正規表現のパターンマッチングを単純な LIKEに変更したことに注意してください。 。これにより、クエリの移植性が少し向上します。もちろん、それを本当に必要な表現に置き換えることもできます。

    db <> fiddle (一部のバリアントを含む)




    1. Laravel 4で列名を取得するにはどうすればよいですか?

    2. MySQLクエリブラウザでクエリパラメータを設定するにはどうすればよいですか?

    3. SQLAlchemyで外部キーのリストを使用してフィールドを作成するにはどうすればよいですか?

    4. SQLのみを使用してMySQL列挙型の値を取得する