루프에 대한 게시물
저는 테이블에서 15,000개의 아이디를 무작위로 25개의 샘플을 얻으려고 합니다.매번 수동으로 실행을 누르는 대신 루프를 수행하려고 합니다.Postgres를 최적으로 사용하는 것은 아니지만, 제가 가지고 있는 도구입니다.지금까지 제가 가진 것은 다음과 같습니다.
for i in 1..25 LOOP
insert into playtime.meta_random_sample
select i, ID
from tbl
order by random() limit 15000
end loop
루프와 같은 절차적 요소는 SQL 언어의 일부가 아니며 절차적 언어 함수, 절차(Postgres 11 이상) 또는 문의 본문 내에서만 사용할 수 있습니다. 여기서 이러한 추가 요소는 각 절차적 언어에 의해 정의됩니다.기본값은 PL/pgSQL이지만 다른 항목도 있습니다.
plpgsql의 예:
DO
$do$
BEGIN
FOR i IN 1..25 LOOP
INSERT INTO playtime.meta_random_sample
(col_i, col_id) -- declare target columns!
SELECT i, id
FROM tbl
ORDER BY random()
LIMIT 15000;
END LOOP;
END
$do$;
루프로 해결할 수 있는 많은 작업의 경우, 더 짧고 빠른 세트 기반 솔루션이 코앞에 있습니다.예제에 해당하는 순수 SQL:
INSERT INTO playtime.meta_random_sample (col_i, col_id)
SELECT t.*
FROM generate_series(1,25) i
CROSS JOIN LATERAL (
SELECT i, id
FROM tbl
ORDER BY random()
LIMIT 15000
) t;
정보:
랜덤 선택의 성능 최적화 정보:
다음은 사용할 수 있는 예입니다.
create temp table test2 (
id1 numeric,
id2 numeric,
id3 numeric,
id4 numeric,
id5 numeric,
id6 numeric,
id7 numeric,
id8 numeric,
id9 numeric,
id10 numeric)
with (oids = false);
do
$do$
declare
i int;
begin
for i in 1..100000
loop
insert into test2 values (random(), i * random(), i / random(), i + random(), i * random(), i / random(), i + random(), i * random(), i / random(), i + random());
end loop;
end;
$do$;
저는 이 질문에 부딪혔고, 오래된 질문이지만, 아카이브에 대한 답변을 추가하기로 했습니다.OP는 루프에 대해 물었지만, 그들의 목표는 테이블에서 임의의 행 샘플을 수집하는 것이었습니다.이 작업을 위해 Postgres 9.5+는 WHERE에 TABLESSAMPLE 절을 제공합니다.여기 좋은 요약이 있습니다.
https://www.2ndquadrant.com/en/blog/tablesample-in-postgresql-9-5-2/
베르누이를 페이지 기반이 아닌 행 기반으로 사용하는 경향이 있지만, 원래 질문은 특정 행 수에 대한 것입니다.이를 위해 다음과 같은 확장 기능이 내장되어 있습니다.
https://www.postgresql.org/docs/current/tsm-system-rows.html
CREATE EXTENSION tsm_system_rows;
그런 다음 원하는 수의 행을 잡을 수 있습니다.
select * from playtime tablesample system_rows (15);
절차적 프로그래밍 언어(예: 파이썬)를 사용하여 연결하고 이러한 유형의 쿼리를 수행하는 것이 더 편리합니다.
import psycopg2
connection_psql = psycopg2.connect( user="admin_user"
, password="***"
, port="5432"
, database="myDB"
, host="[ENDPOINT]")
cursor_psql = connection_psql.cursor()
myList = [...]
for item in myList:
cursor_psql.execute('''
-- The query goes here
''')
connection_psql.commit()
cursor_psql.close()
UUID Array, For loop, Case condition 및 Enum 데이터 업데이트와 관련된 하나의 복잡한 postgres 함수입니다.이 기능은 각 행을 구문 분석하고 조건을 확인하고 개별 행을 업데이트합니다.
CREATE OR REPLACE FUNCTION order_status_update() RETURNS void AS $$
DECLARE
oid_list uuid[];
oid uuid;
BEGIN
SELECT array_agg(order_id) FROM order INTO oid_list;
FOREACH uid IN ARRAY uid_list
LOOP
WITH status_cmp AS (select COUNT(sku)=0 AS empty,
COUNT(sku)<COUNT(sku_order_id) AS partial,
COUNT(sku)=COUNT(sku_order_id) AS full
FROM fulfillment
WHERE order_id=oid)
UPDATE order
SET status=CASE WHEN status_cmp.empty THEN 'EMPTY'::orderstatus
WHEN status_cmp.full THEN 'FULL'::orderstatus
WHEN status_cmp.partial THEN 'PARTIAL'::orderstatus
ELSE null
END
FROM status_cmp
WHERE order_id=uid;
END LOOP;
END;
$$ LANGUAGE plpgsql;
위의 기능을 실행하는 방법
SELECT order_status_update();
절차를 사용합니다.
CREATE or replace PROCEDURE pg_temp_3.insert_data()
LANGUAGE SQL
BEGIN ATOMIC
INSERT INTO meta_random_sample(col_serial, parent_id)
SELECT t.*
FROM generate_series(1,25) i
CROSS JOIN LATERAL (
SELECT i, parent_id
FROM parent_tree order by random() limit 2
) t;
END;
절차를 호출합니다.
call pg_temp_3.insert_data();
PostgreSQL 매뉴얼: https://www.postgresql.org/docs/current/sql-createprocedure.html
언급URL : https://stackoverflow.com/questions/19145761/postgres-for-loop
'programing' 카테고리의 다른 글
'table'의 알려진 속성이 아니므로 'dataSource'에 바인딩할 수 없습니다. (0) | 2023.05.31 |
---|---|
이클립스가 Android SDK Content Loader에서 중단됩니다. (0) | 2023.05.31 |
데이터 행에 열이 있는지 확인하는 방법은 무엇입니까? (0) | 2023.05.31 |
포스트그리 재설정SQL 기본 키 - 1 (0) | 2023.05.31 |
빈 UI 테이블 보기를 처리합니다.친숙한 메시지 인쇄 (0) | 2023.05.31 |