我有一个例程(Vb.net应用程序),它使用一个主查询以及另一组(子)查询(主查询生成的每一行一个),以编程方式从sql查询填充datagridview。
我的vb代码也可能很弱,但是我对sql代码有疑问,因为我发出了多个查询,我通常设法使用UNIONs和JOIN将它减少到一个查询但是我对此失败了问题。我觉得我可能会遗漏一些基本原则。
现在,我的第一个QUERY创建了一个包含许多行的数据表。 GroupBy字段有很多种可能性,下面是使用Employee
的示例select T.EmployeeID, sum(t.tehours) as 'Hours'
from TimeEntry as t
inner join Project as p on p.projectid=t.ProjectID
inner join employee as E on E.Employeeid=t.employeeid
inner join Activity as A on A.activityid=t.activityid
where p.active=1 AND t.tedate >='8/1/2015' and e.empother1='OFC1'
and a.discipline='X' and t.projectid not like 'O-%'
GROUP BY T.EmployeeID with rollup order by hours desc
SAMPLE RESULTS: GROUPBY HOURS George 10.0 Fred 19.2 Jose 4.4 TOTAL 33.6
然后,我在vb中运行循环以获取每行的总发票(如果有),其中发票日期与时间条目在相同的日期范围内。所以,这里是上面第一行的查询,其中E.EmployeeID ='George'
select sum(TT.ServiceAmt) as 'Invoiced'
from TransactionTable as TT
WHERE TT.InvoiceDate>-'08/01/2015' AND
TT.PROJECTID in
(select t.projectid from TimeEntry as t
inner join Project as p on p.projectid=t.ProjectID
inner join employee as E on E.Employeeid=t.employeeid
inner join Activity as A on A.activityid=t.activityid
where p.active=1 AND t.tedate >='8/1/2015' and e.empother1='OFC1'
and e.employeeID='GEORGE'
and a.discipline='X' and t.projectid not like 'O-%' )
这会产生空字符串或值。如果为null,则替换为零。通过对原始结果中的每一行运行此查询,我们获得了一个如下所示的表:
GROUPBY HOURS INVOICED George 10.0 $1000 Fred 19.2 $1000 Jose 4.4 $0 TOTAL 33.6 $1000
如果发票是固定费用,则不是每位员工定义的。因此,如果George和Fred下面的发票$来自同一张发票,那么总额可能是1000美元而不是2000美元。如果是不同的发票,则为2000美元。
注意:当最左边的列(GROUPBY)使用ProjectID时,这相对容易,因为该字段存在于发票交易表中。我的例子特别避免了这个,因为这是我试图解决的问题。
我的代码现在“有效”,但我想避免慢循环。也许我不能给出复杂性和灵活性。
答案 0 :(得分:0)
似乎第一个查询在错误的级别提供结果,您必须再次将其注入第二个查询。
相反,您可以将第一个查询更改为:
select p.ProjectId, T.EmployeeID, sum(t.tehours) as 'Hours'
from TimeEntry as t
inner join Project as p on p.projectid=t.ProjectID
inner join employee as E on E.Employeeid=t.employeeid
inner join Activity as A on A.activityid=t.activityid
where p.active=1 AND t.tedate >='8/1/2015' and e.empother1='OFC1'
and a.discipline='X' and t.projectid not like 'O-%'
GROUP BY p.ProjectId, T.EmployeeID with rollup order by hours desc
在第二个查询中直接使用ProjectID值:
SELECT SUM(TT.ServiceAmt) AS 'Invoiced'
FROM TransactionTable as TT
WHERE TT.InvoiceDate>-'08/01/2015' AND
TT.PROJECTID = <ID of a Project from first query>
关于业务规则和架构的几个问题:
Transactions
表是否有对Employee
表的引用?您的方法一起出错,因为根据上述问题的答案,您只能提供正确的信息以便按项目计费。
答案 1 :(得分:0)
这几乎可以满足我的需求并快速运行。我可以使用我想要的任何GROUP BY,它是一个查询。感谢您帮我思考。
SELECT WORKED.GroupBY, WORKED.Hours, WORKED.Effort, WORKED.Billable, WORKED.COST, INV.invoiced
FROM (
select T.EmployeeID as 'GroupBy', sum(t.tehours) as 'Hours'
from TimeEntry as t
inner join Project as p on p.projectid=t.ProjectID
inner join employee as E on E.Employeeid=t.employeeid
inner join Activity as A on A.activityid=t.activityid
where p.active=1 AND t.tedate >='8/1/2015' and e.empother1='OFC1'
and a.discipline='X' and t.projectid not like 'O-%'
GROUP BY T.EmployeeID with rollup
) as WORKED
LEFT JOIN
( select T.EmployeeID as 'GroupBy', sum(TT.ServiceAmt)/count(T.EmployeeID) as 'Invoiced'
from TransactionTable as TT
inner join TimeEntry as T on T.ProjectID=TT.ProjectID
inner join Project as p on p.projectid=t.ProjectID
inner join employee as E on E.Employeeid=t.employeeid
inner join Activity as A on A.activityid=t.activityid
WHERE TT.InvoiceDate>-'08/01/2015' AND
TT.PROJECTID in
(select t.projectid from TimeEntry as t
inner join Project as p on p.projectid=t.ProjectID
inner join employee as E on E.Employeeid=t.employeeid
inner join Activity as A on A.activityid=t.activityid
where p.active=1 AND t.tedate >='8/1/2015' and e.empother1='OFC1'
and e.employeeID='GEORGE'
and a.discipline='X' and t.projectid not like 'O-%'
GROUP BY T.EmployeeID with rollup )
)
as INV on WORKED.GroupBY=INV.GroupBY
ORDER BY Hours DESC