Saya mencoba select * from dua tabel (a dan b) menggunakan gabungan (column a.id and b.id), mengingat jumlah kolom (b.owner) di b lebih kecil dari 3, yaitu kemunculan nama seseorang bisa max 2.

Saya sudah mencoba:

SELECT a.*, COUNT(b.owner) AS b_count

FROM a LEFT JOIN b on a.id = b.id

GROUP BY b.owner HAVING COUNT(b_count) <3

Karena saya cukup baru dalam SQL, saya cukup terjebak di sini. Bagaimana saya bisa menyelesaikan masalah ini? Hasilnya harus semua kolom untuk pemilik yang tidak muncul lebih dari dua kali dalam data.

sql
0
E. van Dongen 12 Mei 2021, 15:28

2 jawaban

Jawaban Terbaik

Kueri yang Anda coba jalankan tidak berfungsi karena kolom tidak ada di klausa GROUP BY.

Saat Anda mengeluarkan semua kolom dari tabel a (dengan SELECT a.*), Anda perlu menyertakan semua kolom tersebut dalam pernyataan GROUP BY, sehingga database memahami grup bidang yang akan dikelompokkan dan lakukan agregasi yang diperlukan (dalam kasus Anda COUNT(b.owner)).

Contoh

Mengingat tabel Anda a memiliki 3 kolom di bawah ini:

CREATE TABLE persons (
  id INTEGER,
  name VARCHAR(50),
  birthday DATE,
  PRIMARY KEY (id)
);

.. dan tabel Anda b berikut dan referensi tabel pertama seperti di bawah ini:

CREATE TABLE sales (
  id INTEGER,
  person_id INTEGER,
  sale_value DECIMAL,
  PRIMARY KEY (id),
  FOREIGN KEY (person_id) REFERENCES persons(id)
);

.. Anda harus menanyakannya dengan menggabungkan COUNT() dengan 3 kolom itu:

SELECT a.id, a.name, a.birthday, COUNT(b.person_id) AS b_count
  FROM persons a 
  LEFT JOIN sales b ON a.id = b.person_id
 GROUP BY a.id, a.name, a.birthday
HAVING COUNT(b.person_id) < 3

Alternatif

Jika total catatan pada tabel ke-2 tidak penting bagi Anda, Anda dapat menggunakan "strategi" yang berbeda di sini untuk menghindari melakukan JOIN di antara tabel (berguna saat menggabungkan dua tabel besar) dan menulis ulang semua kolom dari a pada SELECT+GROUP BY. Dengan mengidentifikasi record yang memiliki kurang dari 3 kejadian terlebih dahulu:

SELECT b.person_id
  FROM sales b
 GROUP BY b.person_id
HAVING COUNT(b.id) < 3;

.. dan menggunakannya dalam klausa WHERE untuk mengambil semua kolom dari tabel pertama hanya untuk id yang dihasilkan dari kueri sebelumnya:

SELECT a.*
  FROM persons a
 WHERE a.id IN (....other query here....);

.. eksekusi terjadi dengan cara yang lebih kronologis dan, mungkin, lebih mudah untuk divisualisasikan sambil semakin akrab dengan SQL:

SELECT a.*
  FROM persons a
 WHERE a.id IN (SELECT b.person_id
                  FROM sales b
                 GROUP BY b.person_id
                HAVING COUNT(b.id) < 3);

DB Fiddle di sini

2
Andre Rodrigues 12 Mei 2021, 15:43

Dalam SQL Standar, Anda dapat menggunakan:

SELECT a.*, COUNT(b.owner) AS b_count
FROM a LEFT JOIN
     b 
     ON a.id = b.id
GROUP BY a.id
HAVING COUNT(b.owner) < 3;

Ini mungkin tidak bekerja di semua database (dan mengasumsikan bahwa a.id adalah unik/kunci utama). Alternatifnya adalah menggunakan subquery yang berkorelasi:

SELECT a.*
FROM (SELECT a.*,
             (SELECT COUNT(*)
              FROM b 
              WHERE a.id = b.id
             ) as b_count
      FROM a 
     ) a
WHERE b_count < 3;
1
Gordon Linoff 12 Mei 2021, 12:31