MySQL: Grup işlevinin geçersiz kullanımı


105

MySQL kullanıyorum. İşte benim şemam:

Tedarikçiler ( sid: integer , sname: string, adres dizesi)

Parçalar ( pid: tamsayı , pname: dize, renk: dize)

Katalog ( sid: tamsayı, pid: tamsayı , maliyet: gerçek)

(birincil tuşlar kalın yazılmıştır)

En az iki tedarikçi tarafından yapılan tüm parçaları seçmek için bir sorgu yazmaya çalışıyorum:

-- Find the pids of parts supplied by at least two different suppliers.
SELECT c1.pid                      -- select the pid
FROM Catalog AS c1                 -- from the Catalog table
WHERE c1.pid IN (                  -- where that pid is in the set:
    SELECT c2.pid                  -- of pids
    FROM Catalog AS c2             -- from catalog
    WHERE c2.pid = c1.pid AND COUNT(c2.sid) >= 2 -- where there are at least two corresponding sids
);

Öncelikle, bunu doğru yoldan mı yapıyorum?

İkincisi, bu hatayı alıyorum:

1111 - Grup işlevinin geçersiz kullanımı

Neyi yanlış yapıyorum?

Yanıtlar:


176

Kullanman gerek HAVING, değil WHERE.

Aradaki fark şudur: WHEREMySQL'in seçtiği satırların cümle tümcesi filtreleri. Ardından MySQL, satırları bir arada gruplandırır ve COUNTişleviniz için sayıları toplar .

HAVINGgibi WHEREsadece bu olur, sonraCOUNT değeri hesaplanmış olan beklediğiniz gibi bu ödeme şekli, böylece. Alt sorgunuzu şu şekilde yeniden yazın:

(                  -- where that pid is in the set:
SELECT c2.pid                  -- of pids
FROM Catalog AS c2             -- from catalog
WHERE c2.pid = c1.pid
HAVING COUNT(c2.sid) >= 2)

25
Ayrıca GROUP BY kullanılırsa, VARING, GROUP BY
Viacheslav'dan

1
Ayrıca, GROUP BY OLMADAN önce olmalıdır .... Bandolero'nun yorumunu okumalıydı: D
Andrew

9

İlk olarak, aldığınız hata, COUNTişlevi kullandığınız yerden kaynaklanmaktadır - içinde bir toplama (veya grup) işlevi kullanamazsınız.WHERE cümlecikte .

İkinci olarak, bir alt sorgu kullanmak yerine tabloyu kendisine birleştirmeniz yeterlidir:

SELECT a.pid 
FROM Catalog as a LEFT JOIN Catalog as b USING( pid )
WHERE a.sid != b.sid
GROUP BY a.pid

Sadece en az iki satırın aynı olduğu pidancak en az 2 sids olduğu satırları döndürmesi gerektiğine inanıyorum . Her bir satırı geri aldığınızdan emin olmak için pidbir gruplama cümlesini uyguladım.


Katılmaya ihtiyacım olmaması mümkün mü? (olası bir çözümü sağladığım güncellenmiş cevabıma bakın.)
Nick Heiner

@Rosarch, COUNT(DISTINCT sid)güncellenmiş sorgunuzda kullanmak isteyeceğinizi düşünüyorum .
Mark Elliot

sidZaten her zaman farklı olmak zorunda değilsiniz , çünkü sidve pidbirlikte birincil anahtar oluşturuyor Catalogmu?
Nick Heiner
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.