2012-09-24 2 views
2

나는 우편 번호 내림차순으로 분류, 그룹화되어야 우편 번호에 의해 발견 다음과 같은 조건오라클이 GROUP BY 표현이 아닌 이유는 무엇입니까?

  1. 모든 항목과 오라클 데이터베이스 테이블에서 데이터를 가져 오지하려합니다.
  2. 도시에서 찾은 항목을 그룹화하고 사전 순으로 정렬해야합니다.
  3. dealername에서 찾은 모든 항목을 그룹화하고 사전 순으로 정렬해야합니다.

내가

SELECT DISTINCT ba.uuid AS uuid 
     , COUNT(*) over() AS rowcount 
FROM basicaddress ba 
WHERE ba.postalcode='143456' 
OR ba.lastname LIKE '%143456%' 
OR ba.city LIKE '%143456%' 
GROUP BY 
    CASE WHEN ba.postalcode='143456' THEN ba.postalcode END 
ORDER BY 
    CASE WHEN ba.postalcode='143456' THEN ba.postalcode END DESC, 
    CASE WHEN ba.lastname LIKE '%143456%' THEN ba.lastname END ASC, 
    CASE WHEN ba.city LIKE '%143456%' THEN ba.city ELSE ba.postalcode END DESC 

아래에이 쿼리는 MYSQL에서 잘 작동하지만 오라클은

"표현 BY하지 않는 그룹을"말처럼 쿼리를 쓴 위의 조건을 staisfy하려면 어떤 도움도 크게 평가 될 것입니다.

+0

아니, 이것은 어떤 SQL 언어에 오류를 제공해야합니다. –

+0

@ypercube'select ename, dept by empt group by dept'는 MySQL에서 작동하지만, ename은 동일하게 보장되지 않습니다. 그룹에서 하나를 선택했습니다. 나는 특히 초보자를위한 미스와 오류 소스에 동의합니다. –

+0

@ 플로린 : 나는 그것을 언급하지 않았습니다. 질문의 초판을보십시오. 'CASE' 표현식이 유효하지 않습니다. –

답변

1

이것은 MySQL이 SQL의 논리를 깨뜨리기 때문에 발생합니다.

id ename dept 
1 mark 10 
2 John 10 
3 Mary 10 
4 Jane 20 

쿼리 :

select dept, ename 
from emp 
group by dept; 

당신이 무엇을 얻을 것이다

은의 우리가 테이블 EMP 있다고 가정 해 봅시다? 두 개의 부서가 있기 때문에 두 줄을 가져야하지만 쿼리에서 ename을 요청합니다. 20은 분명하지만 10은 엔진이 무엇을 반환해야합니까?

오류를 반환합니다. ename이 무엇인지 짐작할 수 없습니다. 오라클은 오류를 발생 시켰습니다 - 귀하의 오류, 그러나 MySQL은 ename을 얻었습니다. 그건 미혹이며 버그를 일으킬 수 있습니다.

올바른 쿼리는 다음과 같습니다

select dept, max(ename) --the latest, alaphabeticaly 
from emp 
group by dept; 

--all enames and groups 
select dept, ename 
from emp 
group by dept, ename; 

당신이이 부분을 해결 한 후

, 당신은

COUNT(*) over() AS rowcount 

부분을 해결해야합니다. 오라클 (AFAIK)에서는 분석 함수를 그룹 쿼리와 함께 사용할 수 없습니다.

0

MySQL은 SQL에 대한 뻔한 해석이 있기 때문에 MySQl에서 작동합니다.

올바른 방언에서는 SELECT 또는 ORDER BY 절의 모든 항목이 집계 함수 또는 GROUPed 표현식이어야합니다.

적어도 ba.uuid, 성 및 도시별로 그룹화해야합니다.

1

질문에 대한 구체적인 대답은 uuid이 (가) 그룹별로 표현에 포함되어 있지 않다는 것입니다. 다른 대답은 이미 MySQL (mis) 기능을 설명해주었습니다.쿼리를 쉽게 고정 할 수 있습니다.

SELECT ba.uuid AS uuid, COUNT(*) over() AS rowcount 
FROM basicaddress ba 
WHERE ba.postalcode='143456' OR ba.lastname LIKE '%143456%' OR ba.city LIKE '%143456%' 
GROUP BY uuid, 
     CASE WHEN ba.postalcode='143456' THEN ba.postalcode END 
ORDER BY 
     max(CASE WHEN ba.postalcode='143456' THEN ba.postalcode END) DESC, 
     max(CASE WHEN ba.lastname LIKE '%143456%' THEN ba.lastname END) ASC, 
     max(CASE WHEN ba.city LIKE '%143456%' THEN ba.city ELSE ba.postalcode END) 

또한 그룹 별을 사용할 때 중복되는 "distinct"도 제거했습니다.

그렇다고해서 이것이 원래 질문을 어떻게 만족시키는 지 모르겠습니다. 나는 다음의 라인을 따라 뭔가 더 기대 :

select (case when postalcode is not null then postalcode 
      when city is not null then city 
      when lastname is not null then lastname 
     end), 
     (case when postalcode is not null then 1 
      when city is not null then 2 
      when lastname is not null then 3 
     end), 
     count(*) 
from basicaddress ba 
group by (case when postalcode is not null then postalcode 
       when city is not null then city 
       when lastname is not null then lastname 
      end), 
     (case when postalcode is not null then 1 
      when city is not null then 2 
      when lastname is not null then 3 
     end) 
order by 1, 2 

이 정확하게 당신이 필요하지 않을 수 있지만, 올바른 방향을 가리켜 야합니다. 또한 이것은 표준 SQL이며 두 데이터베이스 모두에서 작동합니다.

0

내가 MySQL을 모르는,하지만 오라클 11g의 다음 작품 :

With 
T_PATTERN as (select '%143456%' as PATTERN from DUAL) 
, T_INPUT as (
    select 1 as UUID, 'X143456y' as FIRSTNAME, 'last1' as LASTNAME, 'u143456v' as CITY, 'w143456z' as POSTALCODE from DUAL union 
    select 2 as UUID, 'first2' as FIRSTNAME, 'a143456b' as LASTNAME, 'a143456b' as CITY, 'postal2' as POSTALCODE from DUAL union 
    select 3 as UUID, 'first3' as FIRSTNAME, 'last3' as LASTNAME, 'c143456d' as CITY, 'postal3' as POSTALCODE from DUAL union 
    select 4 as UUID, 'first4' as FIRSTNAME, 'last4' as LASTNAME, 'city4' as CITY, 'postal4' as POSTALCODE from DUAL 
), 
Q_FNAME as (
    select TI.UUID, TI.FIRSTNAME, COUNT(*) FN_COUNT from T_INPUT TI inner join T_PATTERN TP on 1=1 
    where UPPER(TI.FIRSTNAME) like TP.PATTERN 
    GROUP BY TI.UUID, TI.FIRSTNAME 
), 
Q_LNAME as (
    select TI.UUID, TI.LASTNAME, COUNT(*) LN_COUNT from T_INPUT TI inner join T_PATTERN TP on 1=1 
    where UPPER(TI.LASTNAME) like TP.PATTERN 
    group by TI.UUID, TI.LASTNAME 
), 
Q_CITY as (
    select TI.UUID, TI.CITY, COUNT(*) CT_COUNT from T_INPUT TI inner join T_PATTERN TP on 1=1 
    where UPPER(TI.CITY) like TP.PATTERN 
    group by TI.UUID, TI.CITY 
), 
Q_PCODE as (
    select TI.UUID, TI.POSTALCODE, COUNT(*) PC_COUNT from T_INPUT TI inner join T_PATTERN TP on 1=1 
    where UPPER(TI.POSTALCODE) like TP.PATTERN 
    group by TI.UUID, TI.POSTALCODE 
) 
select TI.UUID, TI.FIRSTNAME, TI.LASTNAME, TI.CITY, TI.POSTALCODE, 
    QF.FN_COUNT, QL.LN_COUNT, QC.CT_COUNT, QP.PC_COUNT 
from T_INPUT ti 
left join Q_FNAME QF on TI.UUID=QF.UUID 
left join Q_LNAME QL on TI.UUID=QL.UUID 
left join Q_CITY QC on TI.UUID=QC.UUID 
left join Q_PCODE QP on TI.UUID=QP.UUID 
order by ti.UUID;