SQL查询中的SQL查询求和

SQL查询中的SQL查询求和,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有两张桌子,员工和员工休假。我正在尝试执行一个SQL查询,以获取每个员工截至今天的休假时间和当前余额的总和。以下是我当前的SQL查询: SELECT e.PIN, e.FirstName, e.LastName, e.Uniform, e.AL_Cap, ev.Value AS '10/1 Balance', (SELECT SUM(value) FROM EmployeeVacations WHERE C

我有两张桌子,员工和员工休假。我正在尝试执行一个SQL查询,以获取每个员工截至今天的休假时间和当前余额的总和。以下是我当前的SQL查询:

SELECT
    e.PIN,
    e.FirstName,
    e.LastName,
    e.Uniform,
    e.AL_Cap,
    ev.Value AS '10/1 Balance',
    (SELECT
        SUM(value)
    FROM EmployeeVacations
    WHERE CreationDate >= '2016-10-01'
    AND Vacation_Type = 'Taken'
    AND Vacation_Kind = 'AL'
    AND EmployeeId = 13)
    AS Taken
FROM    employees e,
        EmployeeVacations ev
WHERE e.Id = ev.EmployeeId
AND ev.IsHistory = 0
AND ev.Vacation_Type = 'Forward'
AND ev.Vacation_Kind = 'AL'
AND EmployeeId = 13
ORDER BY e.LastName, e.FirstName

如果我只选择一个员工,这就行了。如果我删除“where EmployeeId=13”,我会得到一个所有员工的列表,其中包含每行中每个人的总假期总和(比如1300小时)。如何对其进行分解,使其仅显示每个员工的具体数据?

您需要一个相关查询,其中子查询使用来自“父”查询的值


请注意,这可能会非常低效,因为必须对父查询的每一行执行一次内部查询。在许多情况下,您最好将其重新编写为具有适当分组的常规
联接
查询。

您需要一个相关查询,其中子查询使用来自“父”查询的值


请注意,这可能会非常低效,因为必须对父查询的每一行执行一次内部查询。在很多情况下,您最好重新编写一个常规的
连接
查询,并进行适当的分组。

只需猜测您可能还需要总和而不是单个转发记录。。。下面是一个查询,它根据
员工ID
聚合
员工假期

select
  e.pin,
  e.firstname,
  e.lastname,
  e.uniform,
  e.al_cap,
  ev.forward_sum as "10/1 balance",
  ev.taken_sum as taken
from employee e
left join
(
  select     
    employeeid,
    sum(case when vacation_type = 'Forward' 
             and ishistory = 0 then value else 0 end) as forward_sum,
    sum(case when vacation_type = 'Taken' 
             and creationdate >= '20161001' then value else 0 end) as taken_sum,
  from employeevacations
  where vacation_kind = 'AL'
  group by employeeid
) ev on ev.employeeid = e.employeeid
order by e.lastname, e.firstname;

  • 使用显式连接,而不是1992年以前的逗号分隔连接,以提高可读性并减少出错的可能性
  • 别名使用双引号;单引号用于字符串文本
  • 使用“yyyymmdd”表示日期;它是SQL Server中支持的日期文字格式

只是猜测您可能还想要总和而不是单个远期记录。。。下面是一个查询,它根据
员工ID
聚合
员工假期

select
  e.pin,
  e.firstname,
  e.lastname,
  e.uniform,
  e.al_cap,
  ev.forward_sum as "10/1 balance",
  ev.taken_sum as taken
from employee e
left join
(
  select     
    employeeid,
    sum(case when vacation_type = 'Forward' 
             and ishistory = 0 then value else 0 end) as forward_sum,
    sum(case when vacation_type = 'Taken' 
             and creationdate >= '20161001' then value else 0 end) as taken_sum,
  from employeevacations
  where vacation_kind = 'AL'
  group by employeeid
) ev on ev.employeeid = e.employeeid
order by e.lastname, e.firstname;

  • 使用显式连接,而不是1992年以前的逗号分隔连接,以提高可读性并减少出错的可能性
  • 别名使用双引号;单引号用于字符串文本
  • 使用“yyyymmdd”表示日期;它是SQL Server中支持的日期文字格式


强调Mac的最后一段。99%的几率可以更高效地编写。如果优化器对同一查询的语义提出了完全不同的执行计划,那将是一个非常糟糕的优化器。因为我不是使用联接的SQL专家,Marc的建议奏效了。谢谢你,马克!强调Mac的最后一段。99%的几率可以更高效地编写。如果优化器对同一查询的语义提出了完全不同的执行计划,那将是一个非常糟糕的优化器。因为我不是使用联接的SQL专家,Marc的建议奏效了。谢谢你,马克!根据您使用的sql server版本的不同,可能会使用窗口函数来处理此问题。您应该使用显式联接,这样更清晰。您将显示一个员工的前传记录列表,每个前传记录以及员工的总记录。这是需要的吗?或者您更希望员工的前文汇总,也就是说,每个员工只有一个结果行?根据您使用的sql server的版本,这可能会使用窗口函数进行处理。您应该使用显式联接--它更清晰。您显示的是员工前文记录的列表,每一个都与员工的所得金额一起。这是需要的吗?或者您更希望员工的前额总和,即每个员工只有一个结果行?我喜欢这个解决方案,它看起来更干净,更有意义。我如何从ev.forward\u sum中减去ev.Taked\u sum到一个新列中?我尝试将sum(ev.forward\u sum-ev.take\u sum)作为“10/24余额”,但它错误地给了我一个组。谢谢如何从
ev.forward\u sum
中减去
ev.taked\u sum
?当然是负号:
ev.forward\u sum-ev.take\u sum
。你额外的
总和
根本没有任何意义。这很有效,谢谢!我想我是想好好想想。我一直认为SQL中的任何计算都需要像excel电子表格中那样使用SUM。我喜欢这个解决方案,它看起来更干净,更有意义。如何将ev.forward\U SUM中的ev.TAKED\U SUM减去到新列中?我尝试将sum(ev.forward\u sum-ev.take\u sum)作为“10/24余额”,但它错误地给了我一个组。谢谢如何从
ev.forward\u sum
中减去
ev.taked\u sum
?当然是负号:
ev.forward\u sum-ev.take\u sum
。你额外的
总和
根本没有任何意义。这很有效,谢谢!我想我是想好好想想。我一直认为SQL中的任何计算都需要像excel电子表格一样使用SUM。