1

次のようなコードがあります。

SELECT *
FROM invoices
LEFT JOIN shipments ON (
    shipments.id = invoices.shipment_id
)
LEFT JOIN details ON (
    details.id = invoices.detail_id
)

基本的には、請求書テーブルから識別子で出荷テーブルと詳細テーブルを検索したいと思います。ただし、次のような方法でこれら 2 つのテーブルを結合したいとも考えています。

SELECT *
FROM shipments
JOIN details ON (shipments.order = details.order)

基本的に、(invoices.shipment_id、invoices.detail_id) のいずれかが見つかった場合に両方のテーブルを取得する方法が必要です。ただし、結合で後のテーブルを参照することはできないため、次のようなことはできません。

SELECT *
FROM invoices
LEFT JOIN shipments ON (
    shipments.id = invoices.shipment_id
    OR shipments.order = details.order
)
LEFT JOIN details ON (
    details.id = invoices.detail_id
)

両方のテーブルをプルしながらこれを行う方法はありますか?

わかりやすくするために編集します。

これはテーブル構造のサンプルです

CREATE TABLE invoices (
    id integer PRIMARY KEY,
    shipment_id integer,
    detail_id integer,
    data text
)

CREATE TABLE shipments (
    id integer PRIMARY KEY,
    data text
)

CREATE TABLE details (
    id integer PRIMARY KEY,
    shipment_id REFERENCES shipments (id),
    data text
)

invoices.shipment_idを含む場合と含まない場合がありshipments.id、 を含む場合と含まinvoices.detail_idない場合がありますdetails.id

有効な ID が含まれている場合invoices.shipment_idは、次のようにする必要があります。

SELECT
    shipments.data as shipment_data,
    details.data as detail_data,
FROM invoices
JOIN shipments ON (invoices.shipment_id = shipments.id)
JOIN details ON (details.shipment_id = shipments.id)

invoices.detail_id有効な ID が含まれている場合は、次のことを行う必要があります。

SELECT
    shipments.data as shipment_data,
    details.data as detail_data,
FROM invoices
JOIN details ON (invoices.detail_id = details.id)
JOIN shipments ON (details.shipment_id = shipments.id)

これら2つをきれいに組み合わせる方法はありますか?

4

5 に答える 5

1

申し訳ありませんが、質問は SQL サーバーに関するものだと思っていたので、構文が間違っていたらすみません。しかし、クエリがpostgresで機能すると確信しています。

これは奇妙に見えます..しかし、私が正しく理解していれば、次のように機能します

SELECT *
FROM shipments INNER JOIN
details ON shipments.order = details.order RIGHT JOIN
invoices ON details.id = invoices.detail_id 
AND shipments.id = invoices.shipment_id
于 2013-10-03T16:03:20.510 に答える
0

私が思いつくことができる最善の方法は、この解決策です:

SELECT DISTINCT * FROM
(
    SELECT
        shipments.data as shipment_data,
        details.data as detail_data,
    FROM invoices
    JOIN shipments ON (invoices.shipment_id = shipments.id)
    JOIN details ON (details.shipment_id = shipments.id)

    UNION

    SELECT
        shipments.data as shipment_data,
        details.data as detail_data,
    FROM invoices
    JOIN details ON (invoices.detail_id = details.id)
    JOIN shipments ON (details.shipment_id = shipments.id)
)

これは最善の解決策ではありませんが、3 つのテーブルすべてのインデックスを適切に使用し、必要に応じて両方のレコード セットを返します。

于 2013-10-03T18:09:09.623 に答える
0

使用UNION ALL:

値を含むことができるのは1 つだけで(invoices.shipment_id, invoices.detail_id)、もう 1 つは NULL である必要があり、実際にはCHECK制約を使用してこのルールを適用していると仮定します。

SELECT s.data AS shipment_data, d.data AS detail_data
FROM   invoices  i
JOIN   shipments s ON s.id = i.shipment_id
JOIN   details   d ON d.shipment_id = s.id

UNION ALL
SELECT s.data, d.data
FROM   invoices  i
JOIN   details   d ON d.id = i.detail_id
JOIN   shipments s ON s.id = d.shipment_id
  • 最初の分岐は、 の場合にのみ値を返しますinvoices.shipment_id IS NOT NULL
  • 2 番目の分岐は、 の場合にのみ値を返しますinvoices.detail_id IS NOT NULL

出来上がり。

あなたのデータベース スキーマには改善の余地があるように感じます。:)

于 2013-10-04T01:34:33.283 に答える