【问题标题】:How do I write my SQL Code in MS Access SQL?如何在 MS Access SQL 中编写我的 SQL 代码?
【发布时间】:2021-02-03 21:21:02
【问题描述】:

表名:记录

ID Date Time Status BoxType Material Rack EmployeeNr Transaction
1 25-05-2020 13:11:12 70 36757 4 4 188 2
2 25-05-2020 13:12:40 71 31178 2 5 188 2
3 25-05-2020 13:13:31 71 31178 2 5 188 102
4 27-05-2020 13:14:14 71 38444 3 2 181 3
5 27-05-2020 13:14:15 71 38444 3 2 181 3
6 27-05-2020 13:14:41 71 38444 3 2 181 3
7 27-05-2020 13:15:10 71 39123 6 5 188 3
8 27-05-2020 13:15:51 71 38444 3 2 181 103
9 27-05-2020 13:16:51 71 38444 3 2 181 103

我想要的所需输出是第 1、6 和 7 行

ID Date Time Status BoxType Material Rack EmployeeNr Transaction
1 25-05-2020 13:11:12 70 36757 4 4 188 2
6 27-05-2020 13:14:41 71 38444 3 2 181 3
7 27-05-2020 13:15:10 71 39123 6 5 188 3

亲爱的开发者朋友们好,

我有这张表“记录”。有两种类型的交易,即。 “正向”和“反向”。正向交易由一位到两位数字表示(从 1 到 30),反向交易由三位数字表示(从 100 到 130) .现在,每一个独特的正向交易都有一个独特的反向交易。 (例如,交易 1 将有 101,交易 2 将有 102,交易 3 将有 103,依此类推

我不想在我的报告中看到反向交易以及它们的正向交易。 (例如 102 和 2、103 和 3)但是,我必须找到匹配的转发交易,其其他列数据(Date、Status、BoxType、Material、Rack、EmployeeNr em>) 与反向交易相同。 (如图所示,记录号 2 和 3)另外,反向交易可以有多个正向交易匹配,我只想跳过那些数量等于 number 的正向交易的反向交易。 (*从表中可以看出,4,5和6号记录匹配到8号和9号记录,所以我想用8和9隐藏4号和5号两条记录)

所以,我尝试编写一个 SQL 查询,但它在 MS 访问中不起作用。感谢您的大力帮助!谢谢!最好的问候。

我的代码

with table_a as (
  select a.*, row_number() over (partitition by Status, BoxType, Material, Rack, EmployeeNr , Transaction) as dup_n --all columns except ID and time.
  ---for multiple entries of same type
  from Records a
  where Transaction<100
  )
   ,table_b as (
  select b.*, (Transaction-100) as type_new,
         row_number() over (partitition by Status, BoxType, Material, Rack, EmployeeNr , Transaction) as dup_n --all columns except time and ID
         ---for multiple entries of same type
  from Records b
  where Transaction>99
  )
select*from(
  select a.* from table_a
  left join table_b
  on <Status, BoxType, Material, Rack, EmployeeNr , Transaction> --all columns except time and ID
  and a.type = b.type_new
  and a.dup_n = b.dup_n
  )
  where a.Transaction is null

【问题讨论】:

  • 那么从显示的样本集中,究竟应该检索哪些记录?编辑问题以将示例数据显示为文本表,而不是图像,与所需的输出相同。
  • @June7 您好 June7,我创建了一个文本表。我希望你现在明白了。非常感谢!
  • 返回 1 和 7 相当简单,之后我就迷路了。我认为每组前 N 个,但 N 在查询对象中不能是动态的。我可能会构建一个 VBA 过程并将记录写入临时表。
  • @June7 以及如何使用 Access VBA 实现这一目标?

标签: sql vba ms-access


【解决方案1】:

Stackoverflow 并非旨在成为一种代码编写服务,但由于您确实尝试过使用 SQL,而我是提出 VBA 的人,而且我对这一挑战很感兴趣,所以这里有一些东西可以让您开始。首先,构建一个“临时”表 - 表是永久的,但记录是临时的 - 与 Records 表具有相同的字段,除了 ID 字段不是自动编号,只是数字类型。将其称为 RecordsSelected 并确保两个表中的字段在设计中的顺序相同。然后,构建三个查询对象。

CntRevs:

SELECT [Date], Status, BoxType, Material, Rack, EmployeeNr, Transaction, 
Count(ID) AS CntRev, Val(Mid([Transaction],2)) AS Forward
FROM Records
WHERE (((Records.Transaction)>100))
GROUP BY [Date], Status, BoxType, Material, Rack, EmployeeNr, Transaction, Val(Mid([Transaction],2));

查询1:

SELECT Records.*
FROM Records 
LEFT JOIN (SELECT Records.* FROM Records 
           WHERE (((Records.Transaction)>100))) AS Reverses 
ON (Records.Date = Reverses.Date) 
AND (Records.Status = Reverses.Status) 
AND (Records.BoxType = Reverses.BoxType) 
AND (Records.Material = Reverses.Material) 
AND (Records.Rack = Reverses.Rack) 
AND (Records.EmployeeNr = Reverses.EmployeeNr)
WHERE (((Reverses.Transaction) Is Null));

查询2:

SELECT Records.*, Forward
FROM CntRevs 
INNER JOIN Records ON (CntRevs.EmployeeNr = Records.EmployeeNr) 
AND (CntRevs.Rack = Records.Rack) 
AND (CntRevs.Material = Records.Material) 
AND (CntRevs.BoxType = Records.BoxType) 
AND (CntRevs.Status = Records.Status) 
AND (CntRevs.Date = Records.Date)
AND (CntRevs.Forward = Records.Transaction);

通用模块中的代码。结果是将所需输出中标识的 3 条记录写入临时表。

Sub Test()
Dim rs1 As DAO.Recordset, rs2 As DAO.Recordset, rs3 As DAO.Recordset, db As DAO.Database
Dim x As Integer
Set db = CurrentDb
db.Execute "DELETE FROM RecordsSelected"
db.Execute "INSERT INTO RecordsSelected SELECT * FROM Query1"
Set rs1 = db.OpenRecordset("SELECT * FROM CntRevs")
Set rs3 = db.OpenRecordset("SELECT * FROM RecordsSelected")
Do While Not rs1.EOF
    Set rs2 = db.OpenRecordset("SELECT * FROM Query2 WHERE Transaction = " & rs1!Forward & " ORDER BY ID DESC")
    If Not rs2.EOF Then
        rs2.MoveLast
        rs2.MoveFirst
        If rs2.recordCount > rs1!CntRev Then
            For x = 1 To rs2.recordCount - rs1!CntRev
                With rs3
                .AddNew
                !ID = rs2!ID
                !Date = rs2!Date
                !Time = rs2!Time
                !Status = rs2!Status
                !BoxType = rs2!BoxType
                !Material = rs2!Material
                !Rack = rs2!Rack
                !EmployeeNr = rs2!EmployeeNr
                !Transaction = rs2!Transaction
                .Update
                End With
                rs2.MoveNext
            Next
        End If
    End If
    rs1.MoveNext
Loop
End Sub

【讨论】:

  • 非常感谢 June7 让我开始使用 VBA!我试图运行 CntRevs,但它给了我一个错误“无法对使用 '*'(记录)选择的字段进行分组”。我尝试在 SELECT 之后放置列名而不是 *,然后它给了我另一个错误“您的查询不包括指定的表达式“ID”作为聚合函数的一部分。”。分组后,我应该添加所有列吗?最好的问候!
  • 非常感谢您的帮助!这个对我有用!你让我的周末!感谢和言语是不够的!!!!!!!!!!周末愉快!热烈的问候。
  • 附注,Date 是保留字,实际上不应该使用保留字作为对象名称。
  • 糟糕,忘记了rs2.MoveNext 行。还应该引用rs1!CntRev 而不是rs2。也许在你实施之后我又做了一些糟糕的编辑。请参阅修改后的代码。
  • 也是Query2结构的变化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 2016-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多