2009-05-06 2 views
3

У меня есть две таблицы: "пользователь" -> "Заказ"MySQL подсчета ребенка строк таблицы с условием

ТАБЛИЦА: Пользователь

user_id 
----------- 
    u1 
    u2 

ТАБЛИЦА: заказ

order_id | user_id | flag 
------------------------- 
    o1 | u1 | fA 
    o2 | u2 | fB 

Y необходимо получить всех пользователей, подсчитывающих, сколько раз заказы с флагом 'fA'

РЕЗУЛЬТАТЫ ЧТО МНЕ НУЖНО:

user_id | orders 
---------------- 
    u1 | 1 
    u2 | 0 

ПОПыТКЕ:

SELECT 
    u.user_id, 
    COUNT(o.order_id) AS orders 
FROM 
    `user` AS u LEFT JOIN 
    `order` AS o USING (user_id) 
WHERE 
    o.flag IS NULL OR 
    o.flag IN ('fA') 
GROUP BY 
    u.user_id; 

Но этот запрос за исключением пользователя = u2, потому что он не имеет приказ с флаг fA; мне нужно пользователя = u2 появляются с заказов = 0

Может быть что-то вроде этого:

SELECT 
    u.user_id, 
    COUNT(o.order_id IF o.flag IN('fA')) OR 0 AS count ... 

Таблицы и данные:

CREATE TABLE `user` (user_id VARCHAR(2) NULL); 
CREATE TABLE `order` (order_id VARCHAR(2) NULL,user_id VARCHAR(2) NULL,flag VARCHAR(2) NULL); 
INSERT INTO `user` VALUES ('u1'), ('u2'); 
INSERT INTO `order` VALUES ('o1','u1','fA'),('o2','u2','fB'); 

ответ

4

Вы должны использовать левое внешнее соединение вместо левого соединения

SELECT 
    u.user_id, 
    COUNT(o.order_id) AS orders 
FROM 
    `user` AS u LEFT OUTER JOIN 
    `order` AS o USING (user_id) 
WHERE 
    o.flag IS NULL OR 
    o.flag IN ('fA') 
GROUP BY 
    u.user_id; 
+0

Привет, я не знаю, как использовать OUTER JOIN и, найти НУ t больше об этом, спасибо за представление меня – 2009-05-06 22:25:16

0

Вы можете попробовать использовать оператор CASE. Я не MYSQL здесь сегодня, поэтому я могу проверить синтаксис, но это должно быть близко к этому:

SELECT u.user_id, 
      CASE 
       WHEN (SELECT COUNT (*) 
         FROM ORDER z 
         WHERE z.user_id = USER.user_id) > 0 
        THEN COUNT (*) 
       ELSE 0 
      END CASE AS cnt 
     FROM USER 
    GROUP BY USER.user_id; 
0

Этот запрос будет работать:

SELECT 
    u.user_id, 
    COUNT(o.order_id) AS orders 
FROM 
    `user` AS u LEFT OUTER JOIN 
    (SELECT user_id, order_id FROM `order` WHERE flag IS NULL OR flag IN ('fA')) as o 
    USING (user_id) 
GROUP BY 
    u.user_id; 
+0

Большое спасибо, работает хорошо; но, необходимо использовать LEFT OUTER JOIN ?, потому что с простым LEFT JOIN работает нормально. Дополнительная информация: Есть ли способ сделать простой запрос SELECT без подвыборов? – 2009-05-06 22:25:57

+0

Я использую LEFT OUTER JOIN, если у пользователя нет записей в таблице заказов. Есть ли причина, по которой вы не предпочитаете решение подзапроса? –

+0

Ну, я написал свой маленький уровень абстракции db для php, работаю так: $ users = new users(); $ results = $ user-> select (array ( // другие параметры ... 'JOIN' => 'array_key_where_previosly_i_defined_join_rules, another_key' )); Параметр «JOIN» просто принимает простые «ключи» с дополнительными модификаторами ALIAS и LEFT, «RIGHT», не принимает пользовательский SELECT в качестве таблицы. (Пример: «JOIN» => «LEFT: key, RIGHT: key AS alias»). Но я думаю, что я решил проблему, я создаю «представление» с пользовательским выбором join, и теперь я могу создать ключ для этой «таблицы просмотра». Я не уверен, чтобы отклонить LEFT [OUTER] JOIN. Еще раз спасибо – 2009-05-06 22:57:46

1

Вы можете попробовать использовать условие в 'ON' заявление о 'LEFT JOIN', как это:

SELECT u.user_id, COUNT(o.user_id) 
FROM user u 
LEFT JOIN `order` o ON u.user_id = o.user_id AND o.flag = 'fA' 
GROUP BY user_id 

Runing example in SQLFiddle

Смежные вопросы