Saya harus menulis kueri yang akan mengimpor beberapa data dari tabel. Struktur tabelnya seperti:

  • Item_ID
  • Menanam
  • Harga

Saya punya meja kedua dengan

  • Item_ID
  • Menanam

Tabel kedua adalah kuncinya, dan saya harus mencocokkan baris dari tabel pertama untuk mendapatkan harga yang valid. Tampaknya mudah, namun: Dalam tabel pertama, tanaman kolom mungkin menentukan pabrik tertentu, atau memiliki nilai 'ALL'. Yang ingin saya lakukan adalah mengambil harga untuk tanaman yang diberikan, jika sudah diatur, atau mendapatkan harga untuk nilai 'ALL' jika tidak ada baris untuk tanaman yang diberikan. Dengan kata lain:

If first.Plant = second.Plant
  return price
Else If first.Plant = 'ALL'
  return price
Else
  return NULL

Saya tidak dapat menggunakan ON first.Plant = second.Plant OR first.Plant = 'ALL' sederhana, karena mungkin ada dua baris: satu untuk tanaman tertentu dan kedua untuk istirahat dengan nilai 'SEMUA'. Saya hanya perlu mengembalikan harga pertama dalam kasus itu. Misalnya.

Item_ID  | Plant  | Price 
  2      |   M1   |  10,0
  2      |  All   |  12,0
  1      |  All   |  9,0

Dalam hal ini untuk Item_ID = 2 dan Plant = M1 satu-satunya harga yang valid = 10, tetapi untuk Item_ID = 2 dan Plant = M2 harga = 12, dan untuk Item_ID = 1 harga = 9

Saya harap Anda mengerti sesuatu setelah penjelasan saya;)

0
Raven2946 17 November 2017, 14:17

1 menjawab

Jawaban Terbaik

Menggunakan ROW_Number dan Ekspresi Tabel Umum Anda dapat memastikan bahwa ROW_NUMBER dipartisi oleh Item_ID dan Plant dan diurutkan sedemikian rupa sehingga jika ada dua baris maka 'Semua' adalah yang kedua. Anda kemudian sederhana memilih baris dengan nomor baris = 1:

Penyiapan

CREATE TABLE #Price
(
    Item_ID int,
    Plant Varchar(20),
    Price Decimal(6,2)
)

CREATE TABLE #Plant
(
    Item_ID int,
    Plant VARCHAR(20)
)

INSERT INTO #Price
VALUES  (2,  'M1', 10.0),
        (2, 'All', 12.0),
        (1, 'All', 9.0)

INSERT INTO #Plant
VALUES (2,  'M1'),
        (2, 'M2'),
        (1, 'M1'),
        (1, 'M2')

Inilah kueri untuk SQL Server>= 2012

;WITH CTE
AS
(
    SELECT PL.Item_ID, PL.Plant, PR.PRice, ROW_NUMBER() OVER (PARTITION BY Pl.Item_ID, Pl.Plant ORDER BY IIF(PR.Plant = 'All', 1, 0)) AS RN
    FROM #Plant PL
    INNER JOIN #Price PR
        ON PL.Item_Id = PR.Item_Id AND  (PL.Plant = PR.Plant OR PR.Plant = 'ALL')
)
SELECT Item_Id, Plant, Price
FROM CTE
WHERE RN = 1

Dan inilah versi menggunakan CASE yang akan berfungsi untuk semua SQL Server>= 2008 R2

;WITH CTE
AS
(
    SELECT PL.Item_ID, PL.Plant, PR.PRice, ROW_NUMBER() OVER (PARTITION BY Pl.Item_ID, Pl.Plant ORDER BY CASE WHEN PR.Plant = 'All' Then 1 Else 0 End) AS RN
    FROM #Plant PL
    INNER JOIN #Price PR
        ON PL.Item_Id = PR.Item_Id AND  (PL.Plant = PR.Plant OR PR.Plant = 'ALL')
)
SELECT Item_Id, Plant, Price
FROM CTE
WHERE RN = 1
0
Steve Ford 17 November 2017, 11:38