ORA-00979, ifadeye göre grup değil


153

ORA-00979'u aşağıdaki sorgu ile alıyorum:

SELECT cr.review_sk, cr.cs_sk, cr.full_name,
tolist(to_char(cf.fact_date, 'mm/dd/yyyy')) "appt",
cs.cs_id, cr.tracking_number
from review cr, cs, fact cf
where cr.cs_sk = cs.cs_sk
and UPPER(cs.cs_id) like '%' || UPPER(i_cs_id) || '%'
and row_delete_date_time is null
and cr.review_sk = cf.review_wk (+)
and cr.fact_type_code (+) = 183050
GROUP BY cr.review_sk, cr.cs_sk, cf.fact_date, cr.tracking_number
ORDER BY cs.cs_id, cr.full_name;

Aynı sorguda hem GROUP BY hem de ORDER BY yan tümcelerine sahip örnekler bulamadım. Gruptaki her alanı birer birer kaldırmayı denedim, ancak yine de aynı hatayı alıyorum.

Yanıtlar:


237

Sonuçların tek bir değere ( , veya ) sıkıştırılması için SELECTiçindeki tüm sütunlarını yerleştirmeli GROUP BYveya üzerlerine işlevler kullanmalısınız .MINMAXSUM

Bunun neden olduğunu anlamak için basit bir örnek: Şöyle bir veritabanınız olduğunu düşünün:

FOO BAR
0   A
0   B

ve sen koşuyorsun SELECT * FROM table GROUP BY foo. Bu, veritabanının sonuç olarak ilk sütunun 0yerine getirilmesi için tek bir satır döndürmesi gerektiği anlamına gelir, GROUP BYancak artık seçilebilecek iki değer vardır bar. Hangi sonucu beklersiniz - Aveya B? Veya veritabanı, sözleşmesine aykırı olarak birden fazla satır döndürmeli GROUP BYmi?


7
Hayır, maddeye göre sıraya
koymana

3
ORDER BY'daki iki sütunu GROUP BY'a eklemeyi denedim. İşe yaradı. Teşekkürler!
Theresa

1
Ya da başka bir deyişle: İki sütununuz ve birincisine göre grubunuz varsa, bu, sonuç satırı başına ikinci sütundan birkaç değer alacağınız anlamına gelir. Yalnızca tek bir sonuç satırı olduğu halde aralarından seçim yapılabilecek birçok değer olduğundan, DB hangisini döndürmelidir? İlk rastladığı şey mi?
Aaron Digulla

7
@AaronDigulla MySQL'in yaptığı budur ve dünya sona ermemiştir: p
Chris Baker

1
Kısmen katılıyorum. Ancak aşağıdaki durumu varsayalım: 4 sütun var: A, B, C ve D. Şimdi (A, B, C) yi bileşik anahtar olarak ayarlıyorum. Sonra "A, B, max (C), D ... grubunu A, B ile seçin" belirsiz değildir, çünkü A, B ve C'nin her kombinasyonu için D zaten tanımlanmıştır. Yine de Oracle işini yapmayı reddediyor.
ga

18

Grup işlevi bağımsız değişkenleri olmayan GROUP BYtüm SELECTifadeleri yan tümceye dahil edin .


9

Oracle'ın bunun gibi sınırlamaları olması çok kötü. Elbette, GROUP BY'da olmayan bir sütunun sonucu rastgele olur, ancak bazen bunu istersiniz. Aptal Oracle, bunu MySQL / MSSQL'de yapabilirsiniz.

AMA Oracle için bir çözüm var:

Aşağıdaki satır çalışmazken

SELECT unique_id_col, COUNT(1) AS cnt FROM yourTable GROUP BY col_A;

Oracle'ı aşağıdaki gibi bazı 0'larla kandırabilirsiniz, sütununuzu kapsam içinde tutmak, ancak ona göre gruplandırmamak için (bunların sayı olduğunu varsayarak, aksi takdirde CONCAT kullanın)

SELECT MAX(unique_id_col) AS unique_id_col, COUNT(1) AS cnt 
FROM yourTable GROUP BY col_A, (unique_id_col*0 + col_A);

@GlennFromIowa verilen sözde tablom yukarıda titizlikle tanımlanmadı ve artık 11g ile bir firma için çalışmadığım için daha iyi bir örnek veremiyorum, ancak en son test ettiğimde bir problemdi.
Joseph Şehvet

4
Sadece meraktan dolayı, rastgele bir sonuç isteyeceğiniz zamanlara örnek nedir? FOO'ya göre gruplandırmak ve BAR için rastgele bir satır almak isteyebileceğiniz herhangi bir neden düşünemiyorum.
Kyle Bridenstine

5

De dahil olmak üzere sayesinde gruplama takdirde GROUP BYmadde, herhangi bir ifade SELECTgrubu bir (veya toplama işlevi ya da birleştirilmiş kolonu) gibi değildir, COUNT, AVG, MIN, MAX, SUMve böylece (üzerindeki Agrega fonksiyonların listesi ) içinde mevcut olması gerekir GROUP BYmadde.

Örnek (doğru yol) (burada employee_idgrup işlevi değildir (toplanmamış sütun), bu nedenle içinde görünmesi gerekirGROUP BY . Buna karşılık, toplam (maaş) bir grup işlevidir (birleştirilmiş sütun), bu nedenle GROUP BYcümlecikte görünmesi gerekmez .

   SELECT employee_id, sum(salary) 
   FROM employees
   GROUP BY employee_id; 

Örnek (yanlış yol) (burada employee_idgrup işlevi değildir ve GROUP BYyan tümcede görünmez , bu da ORA-00979 Hatasına neden olur.

   SELECT employee_id, sum(salary) 
   FROM employees;

Düzeltmek için aşağıdakilerden birini yapmanız gerekir :

  • Listelenen tüm toplu olmayan ifadeleri içer SELECTbendinde GROUP BYfıkra
  • Grup (toplama) işlevini cümleden kaldırın SELECT.

2

Aşağıdakileri yapmalısınız:

SELECT cr.review_sk, 
       cr.cs_sk, 
       cr.full_name,
       tolist(to_char(cf.fact_date, 'mm/dd/yyyy')) "appt",
       cs.cs_id, 
       cr.tracking_number
from review cr, cs, fact cf
where cr.cs_sk = cs.cs_sk
       and UPPER(cs.cs_id) like '%' || UPPER(i_cs_id) || '%'
       and row_delete_date_time is null
       and cr.review_sk = cf.review_wk (+)
       and cr.fact_type_code (+) = 183050
GROUP BY cr.review_sk, cr.cs_sk, cf.fact_date, cr.tracking_number, cs.cs_id, cr.full_name
ORDER BY cs.cs_id, cr.full_name;

1

Aynı hata, UPPER veya LOWER anahtar sözcüğü hem select ifadesinde hem de ifadeye göre gruplandırmada kullanılmadığında ortaya çıkar.

Yanlış: -

select a , count(*) from my_table group by UPPER(a) .

Sağ :-

select UPPER(a) , count(*) from my_table group by UPPER(a) .

1

Gruplama ölçütü, toplama işlevine bağlı olarak bazı verileri toplamak için kullanılır ve bunun dışında, gruplamaya ihtiyaç duyduğunuz sütun veya sütunları koymanız gerekir.

Örneğin:

select d.deptno, max(e.sal) 
from emp e, dept d
where e.deptno = d.deptno
group by d.deptno;

Bu, departmanların maksimum maaşıyla sonuçlanacaktır.

Şimdi d.deptnofrom group by cümlesini atlarsak aynı hatayı verecektir.


1

Diğer yanıtlara ek olarak, bu hata, cümlecik sırasına göre bir tutarsızlık olması durumunda ortaya çıkabilir. Örneğin:

select 
    substr(year_month, 1, 4)
    ,count(*) as tot
from
    schema.tbl
group by
    substr(year_month, 1, 4)
order by
    year_month
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.