web-dev-qa-db-ja.com

3つのテーブルを結合しながら、3番目のテーブルから上位1行の値を取得するmssql

Mssqlは初めてです。ここでは、3つのテーブル間の結合を使用してデータを取得する必要があります。

ヘッダーjoinjoin画像->結果

ヘッダーテーブル:

enter image description here

ラインテーブル:

enter image description here

各ヘッダーレコードには、複数のラインアイテムを含めることができます。

画像表:

enter image description here

各画像には、一意の画像または複数の画像が含まれます。ヘッダーレコードの項目のリストから1つの画像のURLを取得する必要があります。

結果セット:

enter image description here

クエリ:

SELECT HT.O_ID,
       HT.Type,
       HT.Total,
       IM.Image 

FROM HEADER_TABLE HT 

JOIN LINE_ITEM_TABLE LIT 
ON LIT.O_ID = HT.O_ID 

JOIN IMAGE_TABLE IT 
ON IT.IMAGE = LIT.ITEM_ID 

WHERE IT.SECTION = 'Retail'

このクエリは複数の行を返します。ただし、ヘッダーレコードごとに1つの一意の行が必要です。

誰かが私を修正するのを手伝ってくれる?.

4
Zhu

CROSS APPLYからSELECTを使用して、特定の各ヘッダーからのTOP 1画像のみを使用できます。 APPLYは、列または式を外部からそのフィルターまたは結合にリンクする「外出先で」作成できる関数に似ています。

SELECT
    -- Header columns:
    HT.O_ID,
    HT.Type,
    HT.Total,

    -- Columns from the CROSS APPLY result
    I.Image
FROM 
    HEADER_TABLE HT 
    CROSS APPLY (
        SELECT TOP 1 -- Just retrieve 1 row (for each HT row)
            IT.IMAGE
        FROM
            LINE_ITEM_TABLE LIT
            INNER JOIN IMAGE_TABLE IT ON IT.ITEM_ID = LIT.ITEM_ID
        WHERE
            LIT.O_ID = HT.O_ID AND  -- Link the outmost header "HT" record to it's lines "LIT"
            IT.SECTION = 'Retail') AS I

ORDER BY内にCROSS APPLYを追加して、選択する画像を決定できます。 APPLY演算子からの一致するレコードがない場合でもヘッダー行を表示する場合は、CROSS APPLYOUTER APPLYに変更することもできます(IMAGE列はNULL)。

5
EzLo

しかし、ヘッダーレコードごとに1つの一意の行が必要です。

HT.O_IDごとに1つの一意のレコードを意味するのか、返された4つの列すべてについて重複レコードがないのかは、私にはわかりません。

後者の場合は、DISTINCTキーワードをクエリに追加します(スキーマ名を追加します)。

 SELECT DISTINCT HT.O_ID,
           HT.Type,
           HT.Total,
           IT.Image 

    FROM dbo.HEADER_TABLE HT 
    JOIN dbo.LINE_ITEM_TABLE LIT 
    ON LIT.O_ID = HT.O_ID 
    JOIN dbo.IMAGE_TABLE IT 
    ON IT.Item_ID = LIT.ITEM_ID 
    WHERE IT.SECTION = 'Retail';

結果

O_ID    Type    Total   Image
1001    Online  $10 URL

それで解決しない場合

次に、Header_Tableの値でグループ化し、どのImageを保持する必要があるかを決定し、それを連結する必要があります。

SELECT HT.O_ID,
       HT.Type,
       HT.Total,
       MAX(IT.Image) as MaxURL

FROM dbo.HEADER_TABLE HT 
JOIN dbo.LINE_ITEM_TABLE LIT 
ON LIT.O_ID = HT.O_ID 
JOIN dbo.IMAGE_TABLE IT 
ON IT.Item_ID = LIT.ITEM_ID 
WHERE IT.SECTION = 'Retail'
GROUP BY HT.O_ID,HT.Type,HT.Total;

テストデータ

CREATE TABLE dbo.HEADER_TABLE(O_ID int,Type varchar(100),Total varchar(10))
INSERT INTO dbo.HEADER_TABLE(O_ID,Type,Total)
VALUES  (1001,'Online','$10');

CREATE TABLE dbo.LINE_ITEM_TABLE(ID int,O_ID int,Item_ID varchar(4),Line_Total varchar(10));
INSERT INTO dbo.LINE_ITEM_TABLE(ID,O_ID,Item_ID,Line_Total)
VALUES  (1,1001,'P001','$2'),
        (2,1001,'P002','$2'),
        (3,1001,'P003','$2'),
        (4,1001,'P004','$2'),
        (5,1001,'P005','$2');


CREATE TABLE dbo.IMAGE_TABLE(Item_ID varchar(10),Image varchar(100),Section varchar(10))
INSERT INTO dbo.IMAGE_TABLE 
VALUES  ('P001','URL','Retail'),
        ('P002','URL','Retail'),
        ('P003','URL','Stock'),
        ('P004','URL','Retail'),
        ('P005','URL','Retail');
3
Randi Vertongen