私は、クエリのGreenplumはバージョンに次のSQL Serverクエリを変換しようとしています:SQL Serverの:クロスGreenplumは(Postgresのの前LATERAL版)に参加
ことをここでの考え方があること最終テーブルには、過去30日間にアクティブな(つまり製造された)すべての部品プログラムの最新の部品が300個まで含まれています。 the answers to this questionパー
、私は、横方向が横を持っていないのPostgresの古いバージョンを使用している私の組織を除いて、それを行うだろう、JOINことを承知していますので、私が代わりに以下の機能を実現して残っていた。
CREATE FUNCTION BuildActiveParts(p_day INT, p_n INT)
RETURNS SETOF RECORD --TABLE (part_id bigint,file_id int, measure_date timestamp, location varchar(255))
AS $$
DECLARE
part_active RECORD;
part_list RECORD;
BEGIN
FOR part_active IN
SELECT DISTINCT qf.file_id, qf.location
FROM part pt
INNER JOIN file_model qm on qm.file_model_id = pt.file_model_id
INNER JOIN file qf on qf.file_id = qm.file_id WHERE pt.measure_date >= current_date - p_day LOOP
FOR part_list IN
SELECT DISTINCT pt.part_id, qf.file_id, pt.measure_date, qf.location
FROM part pt
INNER JOIN file_model qm on qm.file_model_id = pt.file_model_id
INNER JOIN file qf on qf.file_id = qm.file_id WHERE qf.file_id = part_active.file_id
AND qf.location = part_active.location
ORDER BY pt.measure_date DESC LIMIT p_n LOOP
RETURN NEXT part_list;
END LOOP;
END LOOP;
END
$$ LANGUAGE plpgsql;
-- Later used in:
--Build list of all active programs in last p_day days. This temporary table is a component of a larger function that produces a table based on this and other other calculations, called daily.
-- Note: this insert yields 'function cannot execute because it accesses relation'
INSERT INTO TMP_part_list (part_id, file_id, measure_date, location)
SELECT DISTINCT * FROM BuildActiveParts(p_day, p_n) AS active_parts (part_id int, file_id text, measure_date timestamp, location text)
;
残念ながら、この関数は別のテーブルへの挿入(私のビジネス要件の避けられない現実)で使用されるので、関数が孤立して実行されたときにうれしい幸せな結果を返しますが、その目的に使用しようとすると大きな怒りを感じます目的。私は「代わりにVIEWを作成する」という効果についての提案を見てきましたが、この機能のスクリプトから生じるビューが一部であるため、実際にはオプションではありません。
赤ちゃんのジャングルから数か月にわたる遠足で、私の組織に自分のものを更新してこれを解決するように説得することはできますか?
編集:ここではコメントに基づいて、いくつかの試みは、次のとおりですのでfunction cannot execute on segment because it accesses relation
の仕事しませんでした機能を持つ
試み、:機能なし
DROP FUNCTION IF EXISTS BuildRecentParts(TEXT, TEXT, INT);
CREATE FUNCTION BuildRecentParts(file_id TEXT, location_in TEXT, p_n INT)
RETURNS SETOF RECORD --TABLE (measure_date timestamp, part_id bigint)
AS $$
DECLARE
part_list RECORD;
BEGIN
FOR part_list IN
SELECT DISTINCT pt.measure_date, pt.part_id
FROM part pt
INNER JOIN file_model qm on qm.file_model_id = pt.file_model_id
INNER JOIN file qf on qf.file_id = qm.file_id
WHERE qf.file_id = file_id
AND qf.edl_desc = location_in
ORDER BY pt.measure_date DESC LIMIT p_n LOOP
RETURN NEXT part_list;
END LOOP;
END
$$ LANGUAGE plpgsql;
SELECT DISTINCT qf.file_id, qf.edl_desc, (SELECT pti.measure_date, pti.part_id FROM part pti
INNER JOIN file_model qmi on qmi.file_model_id = pti.file_model_id
INNER JOIN file qfi on qfi.file_id = qmi.file_id
WHERE qfi.file_id = qf.file_id
AND qfi.edl_desc = qf.edl_desc
ORDER BY pti.measure_date DESC LIMIT 300)
FROM part pt
INNER JOIN file_model qm on qm.file_model_id = pt.file_model_id
INNER JOIN file qf on qf.file_id = qm.file_id
WHERE pt.measure_date >= current_date - 30 ;
試みサブクエリが複数の列を持っているため、動作しません。
CREATE TEMPORARY TABLE TMP_TMP1 (part_id bigint, file_id varchar(255), location varchar(255), measure_date timestamp) DISTRIBUTED BY (part_id);
INSERT INTO TMP_TMP1 (part_id, file_id, location, measure_date)
SELECT DISTINCT pt.part_id, qf.file_id, qf.edl_desc, pt.measure_date
FROM part pt
INNER JOIN file_model qm on qm.file_model_id = pt.file_model_id
INNER JOIN file qf on qf.file_id = qm.file_id;
ANALYZE TMP_TMP1;
SELECT DISTINCT t1.file_id, t1.location, (SELECT t2.measure_date, t2.part_id FROM TMP_TMP1 t2
WHERE t2.file_id = t1.file_id
AND t2.location = t1.location
ORDER BY t2.measure_date DESC LIMIT 300)
FROM TMP_TMP1 t1
WHERE t1.measure_date >= current_date - 30;
私も再帰的なCTEを試みましたが、それはサポートされていませんでした。
リンクされた質問の回答には、古いバージョンでLATERALをエミュレートする方法の良い例が含まれています。あなたはそれらを試しましたか? (すなわち、サブSELECT /関数呼び出しを 'SELECT'節a.k.a.の相関サブクエリに入れてください) – pozs
私は「関係にアクセスするので実行できません」と言ってくれました。私はチャンスを得るときに試して編集します。 –
これは、(LATERAL以外の)もう一つの緑色の制限かもしれません:http://stackoverflow.com/questions/21615211/function-cannot-execute-on-segment-because-it-accesses-relation- * Greenplumの関数は次のとおりです。 Postgresに比べて制限されています。関数が "リレーション"(thinkテーブル)にアクセスする場合、別のテーブルの選択でそれを呼び出すことはできません。* - 関数を使用せずに相関サブクエリを試してみてください。 – pozs