2012-06-07 2 views
2

좋아, 내가 중첩 된 SQL 문으로 일하고 있어요 :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 

"Count (A.proposalAmt) as Proposals"는 필터링 된 레코드 수를 제공합니다. (계약 및 완료된 주문 만)

중첩 된 비트 내에서 쿼리는 100 개의 개별 레코드가있는 한 줄 수를 반환하지 않으려합니다. userId별로 그룹화하면 사용자별로 제안서가 표시되지만 나중에 필터링 할 수 있도록 개별 레코드가 없습니다.

내가이 문제를 해결하기 위해 생각할 수있는 몇 가지 방법이 있지만 모두 빨아들입니다. 나는 다른 쿼리를 할 수는 있지만 그게 좋지 않아 내 결과물로는 잘 작동하지 않는다.

데이터베이스는 MySql입니다. 경우에

워크 플로우 내가 제대로 설명하고 있지 않다 :

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

문제 복제 목적으로 사용한 테이블 스키마를 제공하는 것이 너무 어려울까요? 감사. – hannebaumsaway

답변

1

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 

출력은 비슷해야 이것을보십시오 :

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가 이미 처리하지 않는 한)

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