Mysql SQL计数和分组

Mysql SQL计数和分组,mysql,sql,Mysql,Sql,好的,我正在使用嵌套的SQL语句: 我想询问一下我们销售人员最近写的120份建议书。我正在使用嵌套查询从系统中获取最后120个建议,然后根据状态对它们进行筛选,等等 我遇到的问题是如何计算每个销售人员的提案数量 SQL显然是错误的,但这就是我被卡住的地方 SELECT CASE userId WHEN '4' THEN 'AT' WHEN '3' THEN 'EO' WHEN '11' THEN 'CT' WHEN '13' THEN 'MH'

好的,我正在使用嵌套的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条记录的单行计数。如果我按用户ID分组,我会按用户获得提案的数量,但现在我没有个人记录供以后过滤

我可以想出一些办法来解决这个问题,但都很糟糕。我可以再做一次查询,但这并不雅观,也不能很好地处理我的输出

数据库是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
输出应类似于:

编辑:添加了模式

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
试试这个:

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子句过滤有合同的记录。您需要在需要合同总额的地方执行此操作,并且您必须仅将合同金额过滤到具有您的状态的金额。(除非你的DB已经处理好了。)

总建议书|总合同|销售人员|合同总额|平均天数| pTot |命中率$s |命中率#s 30 15 MH 160496 46.8 324122 0.4952 0.5
为问题复制目的提供所用表的架构会不会太麻烦?谢谢
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 
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