【问题标题】:Sql Query statement under microsoft accessmicrosoft access下的sql查询语句
【发布时间】:2011-09-29 06:03:16
【问题描述】:

我有 2 张桌子:

Employee:
    ID
    SalaryPerDay
    overTimeHoursPrice
    .....
    .....

Schedule:
    ID
    EmployeeID
    Date
    Attending  (boolean)
    loan
    discount
    overTimeHours

多对一关系

我想要一个查询返回

[员工姓名]和

[总和(贷款)] 和

[总和(折扣)] 和

[sum(overTimeHours)] 和

[count(attending)] 其中参加 = true 和

[count(attending) * SalaryPerDay] 和

[sum(overTimeHours)* overTimeHoursPrice ] 和

[(count(attending) * SalaryPerDay) + (sum(overTimeHours)* overTimeHoursPrice) - (sum(discount)) - (sum(loan))]

1- 其中 Date >= [date1] 和 Date

2- 其中 Date >= [date1] And Date

(date1 和 date2 和 name 是参数)

【问题讨论】:

    标签: sql ms-access


    【解决方案1】:

    这样的事情应该可以解决问题....

    SELECT 
      emp.EmployeeName, sum_loan, sum_discount, sum_overTimeHours, count_attending, 
      (count_attending*SalaryPerDay) as totalDayPay,
      (sum_overTimeHours*overTimeHoursPrice) as totalOverTimePay,
      ((count_attending*SalaryPerDay) + (sum_overTimeHours*overTimeHoursPrice) -
        sum_discount - sum_loan) as grandTotal
    FROM Employee emp
      INNER JOIN (SELECT
          EmployeeID,
          sum(loan) as sum_loan,
          sum(discount) as sum_discount,
          sum(overTimeHours) as sum_overTimeHours,
          sum(iif(Attending,1,0)) as count_attending
        FROM Schedule
        WHERE Date >= {date1} and Date <= {date2}
        GROUP BY EmployeeID
      ) sch
      ON emp.ID = sch.EmployeeID
    WHERE emp.EmployeeName = {name}
    

    注意两个WHERE 子句。您可以根据需要调整这些以实现您的两种不同的参数化限制。

    编辑#1:
    由于存储在Schedule.Attending 字段中的“布尔”的实际数值存在一些不确定性,我已经调整了上面的查询以明确说明布尔值。为此,我使用了特定于 MSAccess 的表达式函数 IIF()。这是一个比仅仅假设该字段包含10 更强大的解决方案。

    编辑#2: 我还应该注意,语法会根据您使用它的位置而略有不同。以上是派生表的“标准 sql”语法(即INNER JOIN 关键字后面括号内的子查询)。如果您通过 ODBC 连接运行此查询,则上述语法有效。

    但是,如果您尝试在 Access 本身中创建查询,则需要在子查询周围使用带有结尾句点 [ ]. 的方括号,而不是括号 ( )。所以而不是:

    SELECT ... FROM Employee emp INNER JOIN (SELECT ... ) sch ON ...
    

    使用这个:

    SELECT ... FROM Employee emp INNER JOIN [SELECT ... ]. sch ON ...
    

    【讨论】:

    • 当你算参加的时候,你忘记提到哪里参加=真,我可以把这个条件放在哪里
    • true = 1, false = 0 - 所以只需对列求和就足够了。你试过了吗?
    • 不,我还没有尝试,当我尝试时我会告诉你它是否有效,谢谢 lee
    • 我不相信 MS Access 会定期支持 JOIN。您需要添加 INNER 或 OUTER。
    • @Remou - 谢谢。我通常不使用 Access(无论如何已经有一段时间了)。这里需要内部连接。我已经进行了必要的调整。
    【解决方案2】:

    我想你想要:

    SELECT e.EmployeeName, 
       Sum(s.loan) AS SumOfloan, 
       Sum(s.discount) AS SumOfdiscount, 
       Sum(s.overTimeHours) AS SumOfoverTimeHours, 
       Sum(Abs([Attending])) AS Attnd, 
       Sum([SalaryPerDay]*Abs([Attending])) AS SalyAttnd, 
       Sum([overTimeHoursPrice]*[overtimehours]) AS OTCost, 
       Sum(([SalaryPerDay]*Abs([Attending])+[overTimeHoursPrice]*[overtimehours])-([loan]-[discount])) AS Due
    FROM Employee e
    INNER JOIN Schedule s ON e.ID = s.EmployeeID
    WHERE s.Date Between [date1] And [Date2]
    AND EmployeeName = [Name] 
    GROUP BY e.ID, e.EmployeeName
    

    请注意,布尔值是 0 或 -1,因此 [SalaryPerDay]*Abs([Attending] = Salary * 1,如果参加或 0,如果不参加。

    【讨论】:

    • 这假定EmployeeNameEmployee 表中是唯一的。 (即没有两个员工的名字相同)。这可能是也可能不是一个有效的假设。对于大型组织来说,这几乎肯定是无效的。 Employee 表的结构似乎暗示Employee.ID 是唯一字段,而Employee.EmployeeName 没有那么受限。如果多个员工的姓名确实相同,那么您的查询会将他们的结果汇总到一个汇总行中。
    • @李塔。已更正。以上可以在查询设计窗口中构建,对 Access 的新手很有用,我相信 OP 就是这样。
    • 关于@Lee 的评论,AND EmployeeName = [Name] 应该是AND e.ID = [ID: ]
    • 在聚合(分组依据)查询中选择非聚合列是否违法?如果您更改为e.ID 分组,那么我认为e.EmployeeName 需要变成First(e.EmployeeName) 之类的东西。 (请参阅:microsoft docs,“SELECT 字段列表中的所有字段必须包含在 GROUP BY 子句中或作为 SQL 聚合函数的参数包含。”)
    • @danny 你的最后一行简化显示Salary + OT - Discount - Loan 但我想你想要(Salary + OT) - (Loan - Discount) 换句话说,折扣是从贷款中扣除的,而不是从总工资中扣除的。这就是上面显示的内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多