查询计数和不重复

时间:2019-03-20 09:37:18

标签: sql tsql

我应该在T-SQL中从几个表中进行报告。 我可以加入所需的所有表格,但是在我不知道如何获取信息之后。

说明:

我有下表:

Tbl_User (UserId, Username)
Tbl_Customer (CustomeriD, CustomerName)   
Tbl_DocA (DocId, CustomerID, DateCreate, DateAdd, UseriD)    
Tbl_DocB (DocId, CustomerID, DateCreate, DateAdd, UseriD)    
Tbl_DocC (DocId, CustomerID, DateCreate, DateAdd, UseriD)

我正在尝试获取这样的报告:

enter image description here

理解之后,我的想法是在SQL报告中添加一个带有日期的过滤器。

4 个答案:

答案 0 :(得分:3)

您可以将所有文档表合并在一起,并在其中加入用户和客户。

android:layout_height="wrap_content"
android:maxHeight="100dp"

答案 1 :(得分:1)

您可以使用公用表表达式来获取每个客户的每种报告类型的计数,并有条件地汇总特定用户制作的报告,然后将它们加入到customers表中。
这样的事情应该会为您带来预期的结果:

DECLARE @UserId int = 1; -- or whatever the id of the user you need
WITH CTEDocA AS
(
    SELECT CustomerID
         , COUNT(DocId) As NumberOfReports
         , COUNT(CASE WHEN UserId = @UserId THEN 1 END) As NumberOfReportsByUserAzerty
    FROM Tbl_DocA 
    GROUP BY CustomerID
), CTEDocB AS
(
    SELECT CustomerID
         , COUNT(DocId) As NumberOfReports
         , COUNT(CASE WHEN UserId = @UserId THEN 1 END) As NumberOfReportsByUserAzerty
    FROM Tbl_DocB
    GROUP BY CustomerID
), CTEDocC AS
(
    SELECT CustomerID
         , COUNT(DocId) As NumberOfReports
         , COUNT(CASE WHEN UserId = @UserId THEN 1 END) As NumberOfReportsByUserAzerty
    FROM Tbl_DocC
    GROUP BY CustomerID
)

SELECT cust.CustomeriD
      ,cust.CustomerName
      ,ISNULL(a.NumberOfReports, 0) As NumberOfDocA
      ,ISNULL(a.NumberOfReportsByUserAzerty, 0) As NumberOfDocAByAzerty
      ,ISNULL(b.NumberOfReports, 0) As NumberOfDocB
      ,ISNULL(b.NumberOfReportsByUserAzerty, 0) As NumberOfDocBByAzerty
      ,ISNULL(c.NumberOfReports, 0) As NumberOfDocC
      ,ISNULL(c.NumberOfReportsByUserAzerty, 0) As NumberOfDocCByAzerty
FROM Tbl_Customer cust
LEFT JOIN CTEDocA As a
    ON cust.CustomeriD = a.CustomerID
LEFT JOIN CTEDocA As b
    ON cust.CustomeriD = b.CustomerID
LEFT JOIN CTEDocA As c
    ON cust.CustomeriD = c.CustomerID

要按日期过滤,可以在每个常用表表达中添加一个where子句。

顺便说一句,对于三种文档类型,您拥有三个相同的表这一事实表明数据库设计不佳。
如果这些表相同,则应考虑用一个表替换它们,并在该表中添加一列来描述文档类型。

答案 2 :(得分:0)

有几种方法可以做到这一点。所需的一项关键功能是将一个特定的用户与其他用户区分开。这是通过条件聚合完成的。例如:

select
  customerid,
  count(*),
  count(case when userid = <particular user ID here> then 1 end)
from tbl_doca
group by customerid;

这里是一个可能的查询,使用cross join一次让有问题的用户和cross apply来获取数字。

select
  c.customerid,
  c.customername,
  doca.total  as doc_a_total,
  doca.az     as doc_a_by_azerty,
  docb.total  as doc_b_total,
  docb.az     as doc_b_by_azerty,
  docc.total  as doc_c_total,
  docc.az     as doc_c_by_azerty
from tbl_customer c
cross join
(
  select userid from tbl_user where username = 'Azerty'
) azerty
cross apply
(
  select
    count(*) as total,
    count(case when da.userid = azerty.userid then 1 end)n as az
  from tbl_doca da
  where da.customerid = c.customerid
) doca
cross apply
(
  select
    count(*) as total,
    count(case when db.userid = azerty.userid then 1 end)n as az
  from tbl_docb db
  where db.customerid = c.customerid
) docb
cross apply
(
  select
    count(*) as total,
    count(case when dc.userid = azerty.userid then 1 end)n as az
  from tbl_docc dc
  where dc.customerid = c.customerid
) docc
order by c.customerid;

其他选择是将cross apply替换为left outer join和不相关的子查询,或者将子查询放入select子句中。

答案 3 :(得分:0)

合并文档总数是另一种方法。

然后对计数使用条件聚合。

未记事的记事本:

;WITH SPECIFICUSER AS
(
  SELECT UseriD
  FROM Tbl_User 
  WHERE UserName = 'azerty'
),
DOCTOTALS (  
   SELECT CustomeriD, UseriD, 'DocA' AS Src, COUNT(DocId) AS Total
   FROM Tbl_DocA 
   GROUP BY CustomeriD, UseriD

   UNION ALL

   SELECT CustomeriD, UseriD, 'DocB', COUNT(DocId)
   FROM Tbl_DocB
   GROUP BY CustomeriD, UseriD

   UNION ALL

   SELECT CustomeriD, UseriD, 'DocC', COUNT(DocId)
   FROM Tbl_DocC
   GROUP BY CustomeriD, UseriD
) 
SELECT 
 docs.CustomeriD, 
 cust.CustomerName,

 SUM(CASE WHEN usrX.UseriD is not null AND docs.Src = 'DocA' THEN docs.Total ELSE 0 END) AS Total_DocA_userX,
 SUM(CASE WHEN Src = 'DocA' THEN docs.Total ELSE 0 END) AS Total_DocA,

 SUM(CASE WHEN usrX.UseriD is not null AND docs.Src = 'DocB' THEN docs.Total ELSE 0 END) AS Total_DocB_userX,
 SUM(CASE WHEN Src = 'DocB' THEN docs.Total ELSE 0 END) AS Total_DocB,

 SUM(CASE WHEN usrX.UseriD is not null AND docs.Src = 'DocC' THEN docs.Total ELSE 0 END) AS Total_DocC_userX,
 SUM(CASE WHEN Src = 'DocC' THEN docs.Total ELSE 0 END) AS Total_DocC

FROM DOCTOTALS docs
LEFT JOIN Tbl_Customer cust ON cust.CustomeriD = docs.CustomeriD
LEFT JOIN Tbl_User usr ON usr.UseriD = docs.UseriD
LEFT JOIN SPECIFICUSER usrX ON usrX.UseriD = docs.UseriD
GROUP BY docs.CustomeriD, cust.CustomerName
ORDER BY docs.CustomeriD

可以在报告侧设置长列名称