2017-01-31 18 views
0

У меня относительно сложный запрос с некоторыми подзапросами, которые я использую для создания «Leaderboard» для моих торговых представителей. Проблема в том, что первичные данные фильтруются через Sale_Date, в то время как мне нужен один из столбцов, который должен быть отфильтрован Install_Date (только столбец Installs). Я использую Workbench MySQL и стороннюю платформу бизнес-аналитики для вывода данных презентабельно. Ниже приведен упрощенный вариант того, что я сейчас делаю для этого, но он явно не работает или не дает мне то, что я хочу.Добавление столбца в запрос таблицы MySQL

select `Rep`, `Sales`, `Passed Credit`, `Sales Scheduled`, Installs 
from 
    (select Rep_Name as `Rep`, count(*) as `Sales`..., count(...) as `Sales Scheduled` 
     from ss.customers 
      left join ss.users 
       on customers.rep_id = users.id 
     where Sale_Date between curdate() - interval 6 day and curdate() 
     group by Rep_Name with rollup) cust, 
    (select Rep_Name, count(*) as `Installs` 
     from ss.customers 
      left join ss.installs 
       on customers.id = installs.id 
      left join ss.users 
       on customers.rep_id = users.id 
     where Install_Date between curdate() - interval 6 day and curdate() 
     group by Rep_Name) inst 
order by `Sales` desc, `Passed Credit` desc, ..., `Installs` desc 

Выхода я правильно для всех полей в первой таблице «корка», но все мои повторений показать первый «Устанавливает» COUNT возвращаются во второй половине этого запроса ли его 1 или 20 .

Он возвращается что-то вроде этого:

Rep ----- Sales ----- Passed Credit ----- Sales Scheduled ----- Installs 
John | 10  |   7   |   6   |  5 
Mike | 8  |   7   |   6   |  5 
Trey | 8  |   6   |   4   |  5 
Drew | 6  |   3   |   3   |  5 
Angel | 3  |   2   |   4   |  5 
Total | 35  |   25  |   23   |  22 

Инсталляционный таблице не включают также некоторые люди, которые не имеют никаких продаж на этой неделе, но они также не показывают здесь, что они должны быть. В идеале это то, что таблица будет выглядеть следующим образом:

Rep ----- Sales ----- Passed Credit ----- Sales Scheduled ----- Installs 
John | 10  |   7   |   6   |  5 
Mike | 8  |   7   |   6   |  9 
Trey | 8  |   6   |   4   |  4 
Drew | 6  |   3   |   3   |  4 
Angel | 3  |   2   |   4   |  0 
Tracy | 0  |   0   |   0   |  3 
Diego | 0  |   0   |   0   |  1 
Total | 35  |   25  |   23   |  26 

Я пробовал некоторые сумасшедшие комбинации соединений, объединений, а также где заявления. Любые другие идеи о том, как получить это? Любая помощь приветствуется!

Update 1 Благодаря spencer7593 я был в состоянии решить мою проблему колонка «Installs» показывает неправильно с помощью объединения левых. В настоящее время все еще работает над отображением повторений с 0 продажами за неделю, но у них есть установки (из продаж в предыдущие недели).

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

Customers - rep_id, Sale_Date, id, Passed_Credit, Sale_Scheduled 
Users - id (which is customers.rep_id), Rep_Name, Rep_Office_Location 
Installs - id (which is customers.id), Install_Date, Install_Status 

Я знаю, что в нашей базе данных CRM бардак с несколькими столбцами одного и того же имени на разных таблицах, представляющих разные вещи. Я не проектировал его, и это то, с чем мне приходится жить в средние сроки.

ответ

1

Ваш запрос производит декартово произведение двух встроенных видов, cust и inst.

Я подозреваю, что вы хотите «совместить» их на Rep_Name. Замените этот оператор запятой на ключевое слово LEFT JOIN и добавьте пункт ON, чтобы он соответствовал cust.Rep с inst.Rep_Name. Так как вы возвращаете WITH ROLLUP, возможно, вы хотите сопоставить это с общей строкой от inst?

Большинство ссылок на столбцы являются неквалифицированными, поэтому мы не можем определить, в какой таблице содержится какой столбец. (Есть Rep_Name и Sale_Date, исходящие от ss.customers или ss.users?) Я рекомендую вам квалифицировать все ссылки столбцов в качестве помощи будущему читателю и избегать ошибок «неоднозначного столбца», возникающих позже, когда столбцы добавляются в таблицы.

Если вы хотите вернуть все Rep_Name, в том числе тех, кто не Sales, то вам может понадобиться, чтобы переместить условие в предложении WHERE к статье ON (если Sale_Date является ссылкой на колонку в users таблице.)

Создание некоторые предположения о том, какая таблица содержит столбцы, и предполагая, что Rep_Name не равно нулю, что-то вроде этого:

SELECT IFNULL(cust.`Rep_Name`,'Total') AS `Rep` 
    , cust.`Sales` 
    , cust.`Passed Credit` 
    , cust.`Sales Scheduled` 
    , inst.`Installs` 
    FROM (SELECT cc.`Rep_Name` AS `Rep_Name` 
       , COUNT(cu.id) AS `Sales` 
       , ... 
       , COUNT(...)  AS `Sales Scheduled` 
      FROM ss.customers cc 
      LEFT 
      JOIN ss.users cu 
      ON cu.`id` = cc.`rep_id` 
      AND cu.`Sale_Date` BETWEEN CURDATE() - INTERVAL 6 DAY AND CURDATE() 
      GROUP BY cc.`Rep_Name` 
      WITH ROLLUP 
     ) cust 
    LEFT 
    JOIN (SELECT ic.`Rep_Name` AS `Rep_Name` 
       , COUNT(ii.id) AS `Installs` 
      FROM ss.customers ic 
      LEFT 
      JOIN ss.installs ii 
      ON ii.`id` = ic.`id` 
      AND ii.`Install_Date` BETWEEN CURDATE() - INTERVAL 6 DAY AND CURDATE() 
      GROUP BY ic.`Rep_Name` 
      WITH ROLLUP 
     ) inst 
    ON inst.`Rep_Name` <=> cust.`Rep_Name` 
    ORDER 
    BY cust.`Rep_Name` IS NOT NULL DESC 
     , cust.`Sales` DESC 
     , cust.`Passed Credit` DESC 
     , ... 
     , inst.`Installs` DESC 

Примечание: все строки со значением NULL в Rep_Name будет «матч» WITH ROLLUP общая строка. Похоже, вы хотите, чтобы общая строка была последней, поэтому мы можем добавить выражение в ORDER BY, чтобы эта строка была последней.


Followup:

Чтобы получить «ноль» рассчитывает на продажи, сделать таблицу вождения дать вам список всех Rep_Name, и сделать внешнее соединение к столу, который дает вам продажи.

В качестве демонстрации, используя различные имена таблиц

Получить список всех торговых представителей

SELECT r.rep_id, r.rep_name 
    FROM all_reps r 
    ORDER BY r.id 

Чтобы получить список всех торговых представитель вместе с любыми согласующими «продажами», мы можем использовать внешнее соединение. Обратите внимание, что условия для соответствия находятся в предложении ON внешнего соединения, а не в предложении WHERE.

SELECT r.rep_id 
     , r.rep_name 
     , s.sale_date 
    FROM all_reps r 
    LEFT 
    JOIN sales s 
    ON s.rep_id = r.rep_id 
    AND s.sale_date >= TRUNC(NOW()) - INTERVAL 6 DAY 
    ORDER BY r.rep_id, s.sale_date 

Для представителей, которые не имеют никакого «соответствия» строки в продажах, мы получим назад поругался с колоннами из r. И на этих строках столбцы от s будут NULL.

Обратите внимание, что если мы переместили предикат (условие) на s.sale_date к статье WHERE, что бы отфильтровать все строки, которые имеют значение NULL для s.sale_date. И это отрицает «изюминку» соединения и делает его эквивалентным внутреннему соединению.

+0

Вы, сэр, блестящие. Приношу свои извинения за нечеткие столбцы для определенных таблиц и оставляя догадки до вас. Но вы действительно смогли получить большинство из них правильно. Вскоре я обновлю свое оригинальное сообщение, когда я получу минуту. Левое соединение было именно тем, что мне нужно. Я все еще работаю над тем, чтобы забрать этих представителей с 0 продаж за неделю, чтобы заполнить их на столе. В настоящее время экспериментируем с объединением, чтобы добавить их в конец вывода, так как sale_date не является ссылочным столбцом в ss.users. Как только я получу немного дальше, я обновлю вас и сообщение. – Andrew

+0

Чтобы получить «нулевые» подсчеты для «Продажи», сделайте таблицу вождения таблицей, в которой есть все «Rep_Name», и выполните «LEFT JOIN» в таблице, которая имеет связанные продажи. И поставьте предикат (условия) для даты продажи в разделе 'ON', а не в предложении' WHERE'. – spencer7593

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

  • Нет связанных вопросов^_^