Pertanyaan Sql COALESCE seluruh baris?


Saya baru belajar tentang COALESCE dan saya bertanya-tanya apakah mungkin untuk melakukan COALESCE seluruh baris data antara dua tabel? Jika tidak, apa pendekatan terbaik untuk ocehan berikutnya?

Sebagai contoh, saya memiliki dua tabel ini dan mengasumsikan bahwa semua kolom cocok:

tbl_Employees

Id     Name     Email     Etc
-----------------------------------
1      Sue      ...       ...  
2      Rick     ...       ...  

tbl_Customers

Id     Name     Email     Etc
-----------------------------------
1      Bob      ...       ...  
2      Dan      ...       ...  
3      Mary     ...       ... 

Dan meja dengan id:

tbl_PeopleInCompany

Id     CompanyId 
-----------------
1      1
2      1
3      1

Dan saya ingin query data dengan cara yang mendapat baris dari tabel pertama dengan pencocokan id, tetapi mendapat dari tabel kedua jika tidak ada id yang ditemukan.

Jadi, kueri yang dihasilkan akan terlihat seperti:

Id     Name     Email     Etc
-----------------------------------
1      Sue      ...       ...  
2      Rick     ...       ...  
3      Mary     ...       ... 

Di mana Sue dan Rick diambil dari meja pertama, dan Mary dari yang kedua.


5
2017-09-13 20:47


asal


Jawaban:


 SELECT Id, Name, Email, Etc FROM tbl_Employees
      WHERE Id IN (SELECT ID From tbl_PeopleInID)
 UNION ALL
 SELECT Id, Name, Email, Etc FROM tbl_Customers
      WHERE Id IN (SELECT ID From tbl_PeopleInID) AND
            Id NOT IN (SELECT Id FROM tbl_Employees)

Bergantung pada jumlah baris, ada beberapa cara berbeda untuk menulis kueri ini (dengan JOIN dan EXISTS), tetapi coba ini dulu.

Kueri ini pertama-tama memilih semua orang dari tbl_Employees yang memiliki nilai Id dalam daftar target Anda (tabel tbl_PeopleInID). Itu kemudian tambah ke bagian "bawah" dari kumpulan baris ini hasil kueri kedua. Kueri kedua mendapatkan semua baris tbl_Customer dengan Id dalam daftar target Anda tapi tidak termasuk sembarang dengan Id yang muncul di tbl_Employees.

Daftar total berisi orang-orang yang Anda inginkan - semua ID dari tbl_PeopleInID dengan preferensi yang diberikan kepada Karyawan tetapi catatan yang hilang ditarik dari Pelanggan.


7
2017-09-13 20:51



Anda juga dapat melakukan ini:

1) Outer Bergabung dengan dua tabel di tbl_Employees.Id = tbl_Customers.Id. Ini akan memberi Anda semua baris dari tbl_Employees dan meninggalkan kolom tbl_Customers null jika tidak ada baris yang cocok.

2) Gunakan KASUS KAPAN untuk memilih kolom tbl_Employees atau kolom tbl_Customers, berdasarkan apakah tbl_Customers.Id IS NULL, seperti ini:

CASE WHEN tbl_Customers.Id IS NULL THEN tbl_Employees.Name ELSE tbl_Customers.Name END AS Name

(Sintaks saya mungkin tidak sempurna di sana, tetapi tekniknya adalah suara).


3
2017-09-13 20:56



Saya tidak berpikir itu COALESCE fungsi dapat digunakan untuk apa yang Anda pikirkan. COALESCE mirip dengan ISNULL, kecuali memungkinkan Anda untuk melewatinya banyak kolom, dan akan mengembalikan nilai non-null pertama:

SELECT Name, Class, Color, ProductNumber,
COALESCE(Class, Color, ProductNumber) AS FirstNotNull
FROM Production.Product

Artikel ini harus menjelaskan aplikasinya:

http://msdn.microsoft.com/en-us/library/ms190349.aspx

Kedengarannya seperti jawaban Larry Lustig lebih sesuai dengan apa yang Anda butuhkan.


0
2017-09-13 20:52



Ini harus cukup berkinerja baik. Ini menggunakan CTE untuk pada dasarnya membangun meja kecil Pelanggan yang tidak memiliki catatan Karyawan yang cocok, dan kemudian secara sederhana UNIONhasil itu dengan catatan Karyawan

;WITH FilteredCustomers (Id, Name, Email, Etc)
AS
(
    SELECT  Id, Name, Email, Etc
    FROM    tbl_Customers C
            INNER JOIN tbl_PeopleInCompany PIC
            ON C.Id = PIC.Id
            LEFT JOIN tbl_Employees E
            ON C.Id = E.Id
    WHERE   E.Id IS NULL
)

SELECT  Id, Name, Email, Etc
FROM    tbl_Employees E
        INNER JOIN tbl_PeopleInCompany PIC
        ON C.Id = PIC.Id

UNION

SELECT  Id, Name, Email, Etc
FROM    FilteredCustomers

Menggunakan IN Operator dapat agak membebani pertanyaan besar karena mungkin harus mengevaluasi subquery untuk setiap catatan yang sedang diproses.


0
2017-09-13 21:20