41

私はというテーブルを持っていますmap_tags

map_id | map_license | map_desc

widgetsそして、レコードにレコードへの外部キー参照(1から1)が含まれている別のテーブル( ) map_tags

widget_id | map_id | widget_name

すべてmap_licenseのsが一意であるという制約がある場合(ただし、のキーとして設定されていないmap_tags場合)、amap_licenseとaがある場合は、同じSQLステートメント内のすべてwidget_nameに対して挿入を実行します。widgets

INSERT INTO
    widgets w
(
    map_id,
    widget_name
)
VALUES (
    (
        SELECT
            mt.map_id
        FROM
            map_tags mt
        WHERE
            // This should work and return a single record because map_license is unique
            mt.map_license = '12345'
    ),
    'Bupo'
)

私は正しい方向に進んでいると思いますが、これがPostgresのSQLとして正しくないことをすぐに知っています。誰かがそのような単一のクエリを達成するための適切な方法を知っていますか?

4

3 に答える 3

55

ステートメントINSERT INTO SELECTに含まれる定数を含め、バリアントを使用します。SELECT

PostgreSQLのINSERT構文は次のとおりです。

INSERT INTO table [ ( column [, ...] ) ]
 { DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query }
 [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]

上記の2行目の終わりにあるクエリオプションに注意してください。

これがあなたのための例です。

INSERT INTO 
    widgets
    (
        map_id,
        widget_name
    )
SELECT 
   mt.map_id,
   'Bupo'
FROM
    map_tags mt
WHERE
    mt.map_license = '12345'
于 2012-10-22T17:50:51.267 に答える
52
INSERT INTO widgets
(
    map_id,
    widget_name
)
SELECT
    mt.map_id, 'Bupo'
FROM
    map_tags mt
WHERE
    mt.map_license = '12345'
于 2012-10-22T17:51:30.367 に答える
0

クイックアンサー: 「単一のレコード」が ありません。「 1つのレコードで設定された」があります。これがJavaScriptの場合:「1つの値」ではなく「1つの値を持つ配列」があります。

あなたの例では、サブクエリで1つのレコードが返される場合がありますが、それでも、レコードの「配列」を個別の実際のパラメータにアンパックして、1つのパラメータのみを受け取る場所にしようとしています。

「どうして」に頭を包むのに数時間かかりました。私が非常に似たようなことをしようとしていたので:

これが私のメモです:

tb_table01: (no records)
+---+---+---+
| a | b | c | << column names
+---+---+---+

tb_table02:
+---+---+---+
| a | b | c | << column names
+---+---+---+
|'d'|'d'|'d'| << record #1
+---+---+---+
|'e'|'e'|'e'| << record #2
+---+---+---+
|'f'|'f'|'f'| << record #3
+---+---+---+

--This statement will fail:
INSERT into tb_table01
    ( a, b, c )
VALUES
    (  'record_1.a', 'record_1.b', 'record_1.c' ),
    (  'record_2.a', 'record_2.b', 'record_2.c' ),

    -- This sub query has multiple
    -- rows returned. And they are NOT
    -- automatically unpacked like in 
    -- javascript were you can send an
    -- array to a variadic function.
    (
        SELECT a,b,c from tb_table02
    ) 
    ;

基本的に、「VALUES」 をレコードの配列を解凍できる可変個引数とは考えないでください。javascript関数の場合のように、ここで解凍する引数はありません。そのような:

function takeValues( ...values ){ 
    values.forEach((v)=>{ console.log( v ) });
};

var records = [ [1,2,3],[4,5,6],[7,8,9] ];
takeValues( records );

//:RESULT:
//: console.log #1 : [1,2,3]
//: console.log #2 : [4,5,7]
//: console.log #3 : [7,8,9]

SQLの質問に戻ります。

サブセレクションに結果が1つしかないからといって、この機能が存在しないという現実は変わりません。「 1枚のレコード」ではなく「1枚のレコードのセット」です。

于 2018-07-30T00:17:48.787 に答える