Неверная группировка по функции :: MySQL - PullRequest
0 голосов
/ 03 марта 2011

Во-первых, я прочитал посты с совпадающими именами, и я попытался интегрировать некоторые решения, но я не могу заставить этот SQL-запрос работать ...

Проблема, похоже, связана с функцией COUNT в строке 8.

Вот оно ..


SELECT `purchase_orders`.`purchase_order_id`,`purchase_orders`.`sequence_id`,`purchase_orders`.`order_number`,`vendors`.`name`,`purchase_orders`.`date`,COUNT(`purchase_order_items`.`purchase_order_id`) `item_count`,`purchase_orders`.`total_value`,`purchase_orders`.`status`,`users`.`first`
FROM (`purchase_orders`, `vendors`, `purchase_order_items`,`users`) 
WHERE `purchase_orders`.`aid`='c4ca4238a0b923820dcc509a6f75849b'AND`purchase_orders`.`vendor_id`=`vendors`.`vid`AND`purchase_orders`.`created_by`=`users`.`uid`AND`purchase_order_items`.`purchase_order_id`=`purchase_orders`.`purchase_order_id` AND `purchase_orders`.`purchase_order_id` LIKE '%122%' 
OR `purchase_orders`.`aid`='c4ca4238a0b923820dcc509a6f75849b'AND`purchase_orders`.`vendor_id`=`vendors`.`vid`AND`purchase_orders`.`created_by`=`users`.`uid`AND`purchase_order_items`.`purchase_order_id`=`purchase_orders`.`purchase_order_id` AND `purchase_orders`.`sequence_id` LIKE '%122%' 
OR `purchase_orders`.`aid`='c4ca4238a0b923820dcc509a6f75849b'AND`purchase_orders`.`vendor_id`=`vendors`.`vid`AND`purchase_orders`.`created_by`=`users`.`uid`AND`purchase_order_items`.`purchase_order_id`=`purchase_orders`.`purchase_order_id` AND `purchase_orders`.`order_number` LIKE '%122%' 
OR `purchase_orders`.`aid`='c4ca4238a0b923820dcc509a6f75849b'AND`purchase_orders`.`vendor_id`=`vendors`.`vid`AND`purchase_orders`.`created_by`=`users`.`uid`AND`purchase_order_items`.`purchase_order_id`=`purchase_orders`.`purchase_order_id` AND `vendors`.`name` LIKE '%122%' 
OR `purchase_orders`.`aid`='c4ca4238a0b923820dcc509a6f75849b'AND`purchase_orders`.`vendor_id`=`vendors`.`vid`AND`purchase_orders`.`created_by`=`users`.`uid`AND`purchase_order_items`.`purchase_order_id`=`purchase_orders`.`purchase_order_id` AND `purchase_orders`.`date` LIKE '%122%' 
OR `purchase_orders`.`aid`='c4ca4238a0b923820dcc509a6f75849b'AND`purchase_orders`.`vendor_id`=`vendors`.`vid`AND`purchase_orders`.`created_by`=`users`.`uid`AND`purchase_order_items`.`purchase_order_id`=`purchase_orders`.`purchase_order_id` AND COUNT(`purchase_order_items`.`purchase_order_id`) LIKE '%122%'
OR `purchase_orders`.`aid`='c4ca4238a0b923820dcc509a6f75849b'AND`purchase_orders`.`vendor_id`=`vendors`.`vid`AND`purchase_orders`.`created_by`=`users`.`uid`AND`purchase_order_items`.`purchase_order_id`=`purchase_orders`.`purchase_order_id` AND `purchase_orders`.`total_value` LIKE '%122%' 
OR `purchase_orders`.`aid`='c4ca4238a0b923820dcc509a6f75849b'AND`purchase_orders`.`vendor_id`=`vendors`.`vid`AND`purchase_orders`.`created_by`=`users`.`uid`AND`purchase_order_items`.`purchase_order_id`=`purchase_orders`.`purchase_order_id` AND `purchase_orders`.`status` LIKE '%122%' 
OR `purchase_orders`.`aid`='c4ca4238a0b923820dcc509a6f75849b'AND`purchase_orders`.`vendor_id`=`vendors`.`vid`AND`purchase_orders`.`created_by`=`users`.`uid`AND`purchase_order_items`.`purchase_order_id`=`purchase_orders`.`purchase_order_id` AND `users`.`first` LIKE '%122%'  
GROUP BY `purchase_orders`.`purchase_order_id`
ORDER BY `purchase_orders`.`purchase_order_id` ASC 
LIMIT 0,1

Ответы [ 3 ]

1 голос
/ 03 марта 2011

Хотя вы, возможно, выбрали решение своего вопроса, тем не менее, ваш запрос действительно нечист.Исходная посылка SQL состоит в том, чтобы один раз идентифицировать отношения того, как таблица соотносится с заданными ключами, и применять любые дополнительные фильтры в where.Ваш запрос имел «ИЛИ» несколько раз.Вот более точная версия вашего запроса.Обратите внимание, что в предложении where есть ОДИН ключ «помощь», который вы искали, и единственное предложение AND для присоединения к таблицам ... Под запросом находятся остальные предложения AND, в которых у вас было так много элементов с LIKE '% 122%', которыеCOUNT (чего угодно) будет возвращать число.

SELECT 
       po.purchase_order_id,
       po.sequence_id,
       po.order_number,
       v.name,
       po.date,
       COUNT( poi.purchase_order_id) item_count,
       po.total_value,
       po.status,
       users.first
    FROM 
       purchase_orders po,
       vendors v,
       purchase_order_items poi,
       users
    WHERE 
           po.aid = 'c4ca4238a0b923820dcc509a6f75849b'
       AND po.vendor_id = v.vid
       AND po.purchase_order_id = poi.purchase_order_id
       AND po.created_by = users.uid
   GROUP BY 
       po.purchase_order_id
   ORDER BY 
       po.purchase_order_id
   LIMIT 
       0, 1

Это я не понял, что вы искали, но в конечном итоге оказался ПОСЛЕ всех других предложений WHERE, которые у меня были выше ...Опять же, COUNT (poi.purchase_order_id), как "% 122%", я не думаю, что это применимо.Вероятно, другие столбцы на основе «идентификаторов», которые я бы предположил, основаны на числах.

       AND po.purchase_order_id LIKE '%122%' 
       AND po.sequence_id LIKE '%122%' 
       AND po.order_number LIKE '%122%' 
       AND v.name LIKE '%122%' 
       AND po.date LIKE '%122%' 
       AND COUNT(poi.purchase_order_id) LIKE '%122%'
       AND po.total_value LIKE '%122%' 
       AND po.status LIKE '%122%' 
       AND users.first LIKE '%122%'  

Оказалось, что вы НАМЕРЕНЫ применять все условия соединения для каждого экземпляра, но это должно было быть сделано - для пояснения

where 
     ( all first group of conditions )
  OR ( all next group of conditions )
  OR ( all next, etc )

Надеюсь, это поможет прояснить структуру запросов.

1 голос
/ 03 марта 2011

Когда вы используете COUNT(xxx) в SQL, вам нужно использовать его в предложении HAVING:

, например

HAVING COUNT(xxx) > yyyy

Кроме того, обычно вы хотите группировать поля, в которых не используются агрегатные функции. Например:

SELECT person_name
     , SUM(bonuses)
  FROM person x
     , person_bonus y
 WHERE x.person_id = y.person_id

GROUP BY person_name

Поскольку я добавляю дополнительные столбцы к этому оператору SELECT, мне нужно либо использовать для них другую статистическую функцию (COUNT, SUM и т. Д.), Либо использовать GROUP BY для них.

И снова, все, что вы используете для агрегатной функции, может быть использовано в предложении HAVING:

    SELECT person_name
         , SUM(bonuses)
      FROM person x
         , person_bonus y
     WHERE x.person_id = y.person_id
   GROUP BY person_name
     HAVING SUM(bonuses) > 50000  // I wish :)
0 голосов
/ 03 марта 2011

Правила использования предложения GROUP BY:

  1. Столбец, который вы GROUP BY, также должен быть в вашем операторе SELECT.
  2. Не забудьте сгруппировать по столбцу, о котором вы хотите получить информацию, а не по тому, к которому применяется агрегатная функция.

В вашем примере вы проверяете для purchase_order_items.purchase_order_id = purchase_orders.purchase_order_id, а также применяете агрегатную функцию COUNT (purchase_order_items.purchase_order_id)

...