2

次の条件でOracleデータベーステーブルからデータを取得しようとしています

  1. 郵便番号で見つかったすべてのエントリをグループ化し、郵便番号の降順で並べ替える必要があります。
  2. 都市別に見つかったエントリはグループ化して、アルファベット順に並べ替える必要があります。
  3. ディーラー名で見つかったすべてのエントリをグループ化し、アルファベット順に並べ替える必要があります。

上記の条件を満足させるために、以下のようなクエリを書きました

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では正常に機能していますが、Oracleでは「GROUP BY式ではありません」と言っています

どんな助けでも大歓迎です

4

4 に答える 4

1

これは、MySQLがSQLのロジックを壊したという理由だけで起こります。

テーブルempがあるとしましょう:

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

とクエリ:

select dept, ename
from emp 
group by dept;

あなたは何を得るでしょう?2つの部門があるため、2行を取得する必要がありますが、クエリはenameを要求します。20の場合は明確ですが、10の場合、エンジンは何を返す必要がありますか?

エラーを返す必要があります。与えるエナメを推測することはできません。Oracleはエラーを発生させます-あなたのエラーですが、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では、分析関数とgroupbyクエリを混在させることはできません。

于 2012-09-24T12:58:45.123 に答える
1

あなたの質問に対する具体的な答えuuidは、group by式に含まれていないということです。他の回答では、これを可能にする MySQL (ミス) 機能について既に説明されています。クエリの修正は簡単です。

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)

また、group by を使用するときに冗長になるはずの「個別」も削除しました。

とはいえ、これが元の質問をどのように満たしているかわかりません。次の行に沿って、さらに何かを期待します。

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 であり、両方のデータベースで機能します。

于 2012-09-24T13:28:00.210 に答える
0

MySQL についてはわかりませんが、Oracle 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;
于 2012-11-06T13:29:33.167 に答える
0

MySQL は SQL の解釈がお粗末なので、MySQl で動作します。

適切な方言では、SELECTorORDER BY句内のすべてが集約関数または GROUPed 式のいずれかである必要があります。

少なくとも、ba.uuid、lastname、city でグループ化する必要があります。

于 2012-09-24T12:32:37.463 に答える