Выражение «column_name» не присутствует в группе by и не является агрегатной функцией

#sql #apache-spark-sql

#sql #apache-spark-sql

Вопрос:

Выражение «d.kualifikasi_kbli» не присутствует в группе by и не является агрегатной функцией.

Я думаю, что я понимаю, в чем здесь проблема. Я запускаю это в SparkSQL, и он жалуется, что я выбираю поля, которых нет в Group By (из Union Select в моем примере). Но этот же запрос выполняется в Talend. Как это возможно? Я что-то упустил?

Если я не могу заставить это работать таким образом, что эквивалентно инструкции Group By здесь, если я использую Distinct? Результат будет таким же, поскольку я не выполняю никакой агрегации?

 SELECT a.*
FROM
  (SELECT a1.ID_BU,
          a1.Nama,
          a1.ID_Bentuk_BU,
          a1.id_bentuk_usaha,
          a1.ID_Jenis_BU,
          a1.ID_Jenis_BU_kbli,
          a1.Alamat,
          a1.Kodepos,
          a1.Telepon,
          a1.Fax,
          a1.Email,
          a1.website,
          a1.ID_Kabupaten,
          a1.ID_Propinsi,
          a1.NPWP,
          a1.no_spt AS modal_dasar,
          a1.Log,
          a2.BU_Nomor
   FROM bu a1,
        bu_nomor a2
   WHERE a1.`ID_BU`=a2.`ID_BU`
     AND a1.`ID_Propinsi`=a2.`id_Propinsi` ) AS a,

  (SELECT b.ID_BU,
          b.id_sub_klasifikasi_kbli,
          b.kualifikasi_kbli,
          b.ID_Asosiasi_BU,
          b.Propinsi,
          b.tgl_permohonan,
          c.tgl_habis
   FROM
     (SELECT b1.ID_BU,
             b1.id_sub_klasifikasi_kbli,
             b1.kualifikasi_kbli,
             b1.ID_Asosiasi_BU,
             b1.Propinsi,
             b1.tgl_permohonan
      FROM bu_registrasi_history_kbli b1
      WHERE b1.id_status='4'
        AND b1.Tgl_proses<'2018-03-01' )AS b,

     (SELECT c1.ID_BU,
             c1.id_klasifikasi,
             c1.ID_Asosiasi_BU,
             c1.tgl_habis
      FROM bu_sbu_kbli c1
      WHERE c1.tgl_habis>='2018-03-01' )AS c
   WHERE b.ID_BU=c.ID_BU
     AND SUBSTR(b.id_sub_klasifikasi_kbli, 1, 3)=c.id_klasifikasi
     AND b.ID_Asosiasi_BU=c.ID_Asosiasi_BU
   UNION ALL SELECT d.ID_BU,
                    d.id_sub_klasifikasi_kbli,
                    d.kualifikasi_kbli,
                    d.ID_Asosiasi_BU,
                    d.Propinsi,
                    d.tgl_permohonan,
                    e.tgl_habis
   FROM
     (SELECT d1.ID_BU,
             d1.id_sub_klasifikasi_kbli,
             d1.kualifikasi_kbli,
             d1.ID_Asosiasi_BU,
             d1.Propinsi,
             d1.tgl_permohonan
      FROM bu_registrasi_history_kbli_hapus d1
      WHERE d1.id_status='4'
        AND d1.Tgl_proses<'2018-03-01' )AS d,

     (SELECT e1.ID_BU,
             e1.id_klasifikasi,
             e1.ID_Asosiasi_BU,
             e1.tgl_habis
      FROM bu_sbu_kbli_hapus e1
      WHERE e1.tgl_habis>='2018-03-01' )AS e
   WHERE d.ID_BU=e.ID_BU
     AND SUBSTR(d.id_sub_klasifikasi_kbli, 1, 3)=e.id_klasifikasi
     AND d.ID_Asosiasi_BU=e.ID_Asosiasi_BU
   GROUP BY ID_BU,
            id_sub_klasifikasi_kbli
   ORDER BY tgl_habis,
            tgl_permohonan DESC) x1
WHERE a.ID_BU=x1.ID_BU
GROUP BY x1.ID_BU;
  

Комментарии:

1. В MySQL есть эта «функция», позволяющая выбирать негруппированные столбцы, что дает неопределенные результаты.

2. итак, вы говорите, что результат, который я получаю из приведенного выше запроса, если он выполняется в MySQL, будет неверным?

3. Если вы попытаетесь выбрать столбцы, которые не являются ни сгруппированными, ни агрегированными — чего вы ожидаете в результате? Оно может быть неопределенным только потому, что вы не указываете БД, как свести результат нескольких записей в одну запись. БД должна что-то делать с этим. Но я не внимательно изучил ваш запрос. Поэтому я не могу сказать вам, что делать. Просто подумайте о том, каким должен быть ваш результат, а затем агрегируйте или группируйте.

4. итак, вы говорите, что результат, который я получаю из приведенного выше запроса, если он выполняется в MySQL, будет неверным? Оно недетерминировано и может быть неправильным. Представьте, что в группе существует много разных значений для coulmn, тогда как вы хотите получить только одну строку с одним значением — какое значение должен вернуть сервер? он не знает.. Если вам нужно какое-то определенное значение, используйте соответствующую агрегатную функцию (например, MAX() для наибольшего значения из всех возможных). Если вам нужно какое-либо из возможных значений, используйте специальную агрегатную функцию ANY_VALUE(). Если вам не интересно, удалите этот столбец.

Ответ №1:

Вы не выбираете никаких записей из X1 — вы просто используете для фильтрации. Поэтому нет необходимости выбирать все его столбцы.

Попробуйте написать ОБЪЕДИНЕНИЯ, чтобы сделать ваш код более читаемым.

Попробуйте это:

  SELECT a1.ID_BU,
        a1.Nama,
        a1.ID_Bentuk_BU,
        a1.id_bentuk_usaha,
        a1.ID_Jenis_BU,
        a1.ID_Jenis_BU_kbli,
        a1.Alamat,
        a1.Kodepos,
        a1.Telepon,
        a1.Fax,
        a1.Email,
        a1.website,
        a1.ID_Kabupaten,
        a1.ID_Propinsi,
        a1.NPWP,
        a1.no_spt AS modal_dasar,
        a1.Log,
        a2.BU_Nomor
FROM bu a1
INNER JOIN bu_nomor a2
    ON a1.ID_BU=a2.ID_BU
    AND a1.ID_Propinsi=a2.id_Propinsi
INNER JOIN
(
    SELECT b1.ID_BU
    FROM bu_registrasi_history_kbli b1
    INNER JOIN bu_sbu_kbli c1
        ON b1.ID_BU=c.ID_BU     
        AND SUBSTR(b1.id_sub_klasifikasi_kbli, 1, 3)=c1.id_klasifikasi
        AND b1.ID_Asosiasi_BU=c1.ID_Asosiasi_BU
    WHERE b1.id_status='4'
        AND b1.Tgl_proses<'2018-03-01' 

    UNION 

    SELECT d1.ID_BU
    FROM bu_registrasi_history_kbli_hapus d1
    INNER JOIN bu_sbu_kbli_hapus e1
    ON d1.ID_BU=e1.ID_BU
        AND SUBSTR(d.id_sub_klasifikasi_kbli, 1, 3)=e1.id_klasifikasi
        AND d1.ID_Asosiasi_BU=e1.ID_Asosiasi_BU
    WHERE d1.id_status='4'
        AND d1.Tgl_proses<'2018-03-01' 
        AND e1.tgl_habis>='2018-03-01' 
) x1
    ON a1.ID_BU = x1.ID_BU;