好的,我正在使用嵌套的SQL语句:
我想查询我们的销售人员撰写的最新120份提案。我正在使用嵌套查询从系统中获取最后120个提案,然后根据状态等过滤它们......
我遇到的问题是如何获得每个推销员的提案数量?
SQL显然是错误的,但这就是我被困住的地方。
SELECT
CASE userId
WHEN '4' THEN 'AT'
WHEN '3' THEN 'EO'
WHEN '11' THEN 'CT'
WHEN '13' THEN 'MH'
ELSE userId
END AS Salesman,
SUM(contractAmt) as 'Contract Total',
AVG(DATEDIFF(contractDate, proposalDate)) AS averageDays,
SUM(proposalAmt) as pTot,
Count(*) as Contracts,
Count(A.proposalAmt) as Proposals,
(SUM(contractAmt) / SUM(proposalAmt)) AS 'Hit Rate $s',
(Count(*) / Count(A.proposalAmt)) AS 'Hit Rate #s'
FROM
( /* Get the last 120 proposals not in Lead or Proposal status*/
SELECT contractAmt, proposalAmt, contractDate, status, userId,
CASE WHEN proposalDate = '0000-00-00'
THEN CAST(contractDate as Date)
else CAST(proposalDate as Date)
END as proposalDate
FROM project
WHERE (status != 'proposal' and status != 'lead')
/*GROUP BY id*/
ORDER BY contractDate DESC
LIMIT 0, 120) A
WHERE status = 'contract' or status = 'complete'
GROUP BY userId
“计算(A.proposalAmt)作为提案,”这给了我过滤的记录数。 (只有合同和已完成的订单)
在嵌套位中,查询不希望返回包含100个单独记录的一行计数。如果我按userId分组,我会按用户计算提案数,但现在我没有单独的记录供以后过滤。
我可以通过几种方式来解决这个问题,但所有这些方法都很糟糕。我可以做另一个查询,但这不够优雅,并且对我的输出效果不佳。
数据库是MySql。
工作流程,以防我没有正确解释:
For each user ID
Get the last 100 proposals
Count # of proposals by salesman
Total proposal $ amount by salesman
Count # of contract or complete proposals
Total $ amount of contract and complete jobs
# proposals / # contracts = Hit Rate #'s
$ proposals / $ contracts = Hit Rate $'s
AVERAGE(contract date - proposal date) = Average # days in process
输出应类似于:
Salesman Avg Days ProposalTot ContractTot HR $'s Prop # Con # HR#'s -------------------------------------------------------------------------------------- EO | 29.27 | $30,000 | $15,000 | 50% | 30 | 15 | 50%
编辑:添加架构
Table project
=============
id, userId, clientId, contactId, projectName, status, description, creationDate, shipDate, estimateAmt, leadAmt, reestimateAmt, proposalAmt, contractAmt, completeAmt, type, subType, estDate, reestDate, proposalDate, contractDate, completeDate, lostDate, onHoldDate, estShip, reestShip, proposalShip, contractShip, completeShip, casperLink, statusChangeTS
-------------
id int(11) PK
userId int(11)
clientId int(11)
contactId int(11)
projectName varchar(255)
status enum('lead','proposal','contract','complete','onHold','lost')
description text
creationDate date
shipDate date
estimateAmt int(11)
leadAmt int(11)
reestimateAmt int(11)
proposalAmt int(11)
contractAmt int(11)
completeAmt int(11)
type varchar(100)
subType varchar(100)
estDate date
reestDate date
proposalDate date
contractDate date
completeDate date
lostDate date
onHoldDate date
estShip date
reestShip date
proposalShip date
contractShip date
completeShip date
casperLink varchar(20)
statusChangeTS date
答案 0 :(得分:1)
试试这个:
SELECT
Count(*) as 'Total Proposals',
SUM(CASE WHEN status = 'complete' or status = 'contract' THEN 1 ELSE 0 END) as 'Total Contracts',
CASE userId
WHEN '4' THEN 'AT'
WHEN '3' THEN 'EO'
WHEN '11' THEN 'CT'
WHEN '13' THEN 'MH'
ELSE userId
END AS Salesman,
SUM(CASE WHEN status = 'complete' or status = 'contract' THEN contractAmt ELSE 0 END) as 'Contract Total',
AVG(DATEDIFF(contractDate, proposalDate)) AS averageDays,
SUM(proposalAmt) as pTot,
(SUM(CASE WHEN status = 'complete' or status = 'contract' THEN contractAmt ELSE 0 END) / SUM(proposalAmt)) AS 'Hit Rate $s',
(SUM(CASE WHEN status = 'complete' or status = 'contract' THEN 1 ELSE 0 END) / Count(*)) AS 'Hit Rate #s'
FROM
(/* This inner loop only selects the top 100 records */
select * FROM project
WHERE (status != 'proposal' and status != 'lead') and userId = '13'
order by contractDate DESC
LIMIT 0, 30) A
GROUP BY userId
我能够设计的答案是不使用WHERE子句进行过滤,而是使用CASE子句过滤具有契约的记录。您需要在需要合同总额的情况下执行此操作,并且您必须仅将具有您的状态的合同金额过滤掉。 (除非你的数据库已经处理过这个问题。)
Total Proposals | Total Contracts | Salesman | Contract Total | averageDays | pTot | Hit Rate $s | Hit Rate #s 30 15 MH 160496 46.8 324122 0.4952 0.5