SQL Server 2008查询以获取每个卖家和状态的销售计数

时间:2017-09-28 13:17:19

标签: sql-server sql-server-2008

我试图得到这样的东西:

UserID      Processed   Approved    Declined    Returned
----------- ----------- ----------- ----------- -----------
1           5           1           2           2
2           3           1           2           0
5           5           1           2           3
8           4           1           2           1
9           6           1           2           3
11          7           1           2           4
12          8           1           2           1

但我现在得到了这个:

UserID      Processed   Approved    Declined    Returned
----------- ----------- ----------- ----------- -----------
1           4           1           2           1
2           4           1           2           1
5           4           1           2           1
8           4           1           2           1
9           4           1           2           1
11          4           1           2           1
12          4           1           2           1

我是SQL的新手,我不完全确定我做错了什么。这是我的选择:

SELECT u.UserID,
(SELECT COUNT (*) 
FROM  [dbo].[Krdocs_Details] d, [dbo].[Krdocs] e, [dbo].[Statuses] f
WHERE d.Id=e.Id AND f.Code = d.KrStatus AND ((d.KrStatus = 80) OR (d.KrStatus BETWEEN 60 AND 61) OR (d.KrStatus = 70 OR d.KrStatus BETWEEN 90 AND 92))) AS Processed,
(SELECT COUNT (*) 
FROM  [dbo].[Krdocs_Details] d, [dbo].[Krdocs] e, [dbo].[Statuses] f
WHERE d.Id=e.Id AND f.Code = d.KrStatus AND d.KrStatus = 80) AS Approved,
(SELECT COUNT (*) 
FROM  [dbo].[Krdocs_Details] d, [dbo].[Krdocs] e, [dbo].[Statuses] f
WHERE d.Id=e.Id AND f.Code = d.KrStatus AND (d.KrStatus = 70 OR d.KrStatus BETWEEN 90 AND 92)) AS Declined,
(SELECT COUNT (*) 
FROM  [dbo].[Krdocs_Details] d, [dbo].[Krdocs] e, [dbo].[Statuses] f
WHERE d.Id=e.Id AND f.Code = d.KrStatus AND (d.KrStatus BETWEEN 60 AND 61)) AS Returned
FROM [dbo].[Krdocs_Details] d, [dbo].[Krdocs] e, [dbo].[Statuses] f, [dbo].[bsUsers] u
WHERE d.Id=e.Id AND f.Code=d.KrStatus and u.UserID = d.UserProcess
GROUP BY u.UserID
ORDER BY u.UserID

2 个答案:

答案 0 :(得分:2)

我认为你可以使用如下的查询。如果您发布所需输出的样本数据,我可以测试/修改它。

提示: - 使用JOIN语法而不是WHERE来连接表; - 尽量避免多次访问同一个表(比如在字段中使用SELECT = SELECT,就像你一样)

SELECT u.USERID
    , SUM (CASE WHEN d.KrStatus IN (60,61,70,80,90,91,92)  THEN 1 ELSE 0 END) AS PROCESSED
    , SUM (CASE WHEN d.KrStatus IN (80)  THEN 1 ELSE 0 END) AS APPROVED
    , SUM (CASE WHEN d.KrStatus IN (70,90,91,92)  THEN 1 ELSE 0 END) AS DECLINED
    , SUM (CASE WHEN d.KrStatus IN (60,61)  THEN 1 ELSE 0 END) AS RETURNED
FROM Krdocs_Details D
INNER JOIN Krdocs E ON  D.Id=E.Id
INNER JOIN Statuses F ON D.KrStatus=F.Code
INNER JOIN bsUsers U ON D.UserProcess = U.UserID
WHERE d.KrStatus IN (60,61,70,80,90,91,92) 
GROUP BY u.UserID
ORDER BY u.UserID;

或者,如果您愿意避免重复一次

SELECT userID
, APPROVED+DECLINED+RETURNED AS PROCESSED 
, APPROVED
, DECLINED
, RETURNED
FROM (SELECT u.USERID    
    , SUM (CASE WHEN d.KrStatus IN (80)  THEN 1 ELSE 0 END) AS APPROVED
    , SUM (CASE WHEN d.KrStatus IN (70,90,91,92)  THEN 1 ELSE 0 END) AS DECLINED
    , SUM (CASE WHEN d.KrStatus IN (60,61)  THEN 1 ELSE 0 END) AS RETURNED
    FROM Krdocs_Details D
    INNER JOIN Krdocs E ON  D.Id=E.Id
    INNER JOIN Statuses F ON D.KrStatus=F.Code
    INNER JOIN bsUsers U ON D.UserProcess = U.UserID
    WHERE d.KrStatus IN (60,61,70,80,90,91,92) 
    GROUP BY u.UserID) A
ORDER BY UserID

答案 1 :(得分:1)

您可能希望将查询拆分为几个ctes,例如:

WITH cteProcessed AS(
  SELECT d.UserProcess, COUNT(*) cnt 
  FROM  [dbo].[Krdocs_Details] d, [dbo].[Krdocs] e, [dbo].[Statuses] f
  WHERE d.Id=e.Id
    AND f.Code = d.KrStatus
    AND ((d.KrStatus = 80) OR (d.KrStatus BETWEEN 60 AND 61) OR (d.KrStatus = 70 OR d.KrStatus BETWEEN 90 AND 92))
  GROUP BY d.UserProcess
),
cteApproved AS(
  SELECT d.UserProcess, COUNT(*) cnt
  FROM  [dbo].[Krdocs_Details] d, [dbo].[Krdocs] e, [dbo].[Statuses] f
  WHERE d.Id=e.Id AND f.Code = d.KrStatus AND d.KrStatus = 80
  GROUP BY d.UserProcess
),

您可能希望为其他查询重复此操作。之后,您可以查询您的用户表并将其加入您的ctes。

SELECT u.UserID, p.cnt processed_count, a.cnt approved_cnt
  FROM [dbo].[bsUsers] u
  LEFT JOIN cteProcessed p ON u.UserProcess = u.UserID
  LEFT JOIN cteApproved a ON u.UserProcess = a.UserID