我正在try 使用VB.NET中的MS SYS根据开始和结束日期进行查询

ABSEN可以与表HELPERABSEN合并

因此,我想从表PERIOD中获取开始日期和结束日期,其中条件基于表PERIOD中的PERIODNAME.

如果数据的开始日期和结束日期不存在于DATEABSEN字段的Absen表中,则查询根据ID2INOUT创建新记录

我不想使用MS Access中的函数,因为我使用的是VB. NET的SQL.

如果还有其他方法请指导我

谢谢

Public Class Form1
    Private AbsenService As New ABSENservice()
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        DataGridView1.DataSource = AbsenService.GetAbsenfull()
    End Sub
End Class
Public Class ABSENservice
    Public Function GetOledbConnectionString() As String
        Return "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\trialabsen.accdb;Persist Security Info=False;"
    End Function
    Private ReadOnly _conn As OleDbConnection
    Private _connectionString As String = GetOledbConnectionString()
    Public Sub New()
        _conn = New OleDbConnection(_connectionString)
    End Sub
    Public Function GetAbsenfull() As IEnumerable(Of ABSEN)
        Dim sql = $"SELECT ABSEN.ID2 AS [ID2],MASTERID2.NAMEID2 AS [NAMEID2],ABSEN.INOUT AS [INOUT],ABSEN.DATEABSEN AS [DATEABSEN],Format(ABSEN.TIME,'hh:mm:ss') AS [TIME],ABSEN.STATUS AS [STATUS] FROM ABSEN INNER JOIN MASTERID2 ON ABSEN.ID2 = MASTERID2.ID2"
        Using _conn = New OleDbConnection(GetOledbConnectionString())
            Return _conn.Query(Of ABSEN)(sql).ToList()
        End Using
    End Function
End Class
Public Class ABSEN
    Public Property ID() As Integer
    Public Property ID2() As String
    Public Property NAMEID2() As String
    Public Property INOUT() As String
    Public Property DATEABSEN() As DateTime
    Public Property TIME() As String
    Public Property STATUS() As String

End Class

来自代码的结果

ID2 NAMEID2 INOUT DATEABSEN TIME STATUS
1000 JACK IN 21-Apr-24 08:00:00 PRESENT
1000 JACK IN 22-May-24 08:00:00 PRESENT
1000 JACK OUT 22-May-24 17:00:00 PRESENT
1002 KEN IN 22-May-24 08:00:00 PRESENT
1002 KEN OUT 22-May-24 17:00:00 PRESENT
1000 JACK OUT 21-Apr-24 17:00:00 PRESENT
1002 KEN IN 21-Apr-24 08:00:00 PRESENT
1002 KEN OUT 21-Apr-24 17:00:00 PRESENT
1000 JACK IN 22-Apr-24 08:00:00 PRESENT
1000 JACK OUT 22-Apr-24 17:00:00 PRESENT
1002 KEN IN 22-Apr-24 08:00:00 PRESENT
1002 KEN OUT 22-Apr-24 17:00:00 PRESENT
1000 JACK IN 24-Apr-24 08:00:00 PRESENT
1002 KEN OUT 24-Apr-24 17:00:00 PRESENT
1000 JACK OUT 25-Apr-24 17:00:00 PRESENT
1002 KEN IN 25-Apr-24 08:00:00 PRESENT
1000 JACK IN 20-May-24 08:00:00 PRESENT
1000 JACK OUT 20-May-24 17:00:00 PRESENT
1002 KEN IN 20-May-24 08:00:00 PRESENT
1002 KEN OUT 20-May-24 17:00:00 PRESENT
1000 JACK IN 21-May-24 08:00:00 PRESENT
1000 JACK OUT 21-May-24 17:00:00 PRESENT
1002 KEN IN 21-May-24 08:00:00 PRESENT
1002 KEN OUT 21-May-24 17:00:00 PRESENT
1000 JACK IN 20-Apr-24 08:00:00 PRESENT
1000 JACK OUT 20-Apr-24 17:00:00 PRESENT
1002 KEN IN 20-Apr-24 08:00:00 PRESENT
1002 KEN OUT 20-Apr-24 17:00:00 PRESENT

样本数据

ABSEN

ID2 INOUT DATEABSEN TIME STATUS
1000 IN 20-Apr-24 08:00 PRESENT
1000 OUT 20-Apr-24 17:00 PRESENT
1002 IN 20-Apr-24 08:00 PRESENT
1002 OUT 20-Apr-24 17:00 PRESENT
1000 IN 21-Apr-24 08:00 PRESENT
1000 OUT 21-Apr-24 17:00 PRESENT
1002 IN 21-Apr-24 08:00 PRESENT
1002 OUT 21-Apr-24 17:00 PRESENT
1000 IN 22-Apr-24 08:00 PRESENT
1000 OUT 22-Apr-24 17:00 PRESENT
1002 IN 22-Apr-24 08:00 PRESENT
1002 OUT 22-Apr-24 17:00 PRESENT
1000 IN 24-Apr-24 08:00 PRESENT
1002 OUT 24-Apr-24 17:00 PRESENT
1000 OUT 24-Apr-24 17:00 PRESENT
1002 IN 24-Apr-24 08:00 PRESENT
1000 IN 20-May-24 08:00 PRESENT
1000 OUT 20-May-24 17:00 PRESENT
1002 IN 20-May-24 08:00 PRESENT
1002 OUT 20-May-24 17:00 PRESENT
1000 IN 21-May-24 08:00 PRESENT
1000 OUT 21-May-24 17:00 PRESENT
1002 IN 21-May-24 08:00 PRESENT
1002 OUT 21-May-24 17:00 PRESENT
1000 IN 22-May-24 08:00 PRESENT
1000 OUT 22-May-24 17:00 PRESENT
1002 IN 22-May-24 08:00 PRESENT
1002 OUT 22-May-24 17:00 PRESENT

HELPERABSEN

ID2 INOUT DATEABSEN TIME STATUS
1000 IN 23-Apr-24 NOT PRESENT
1000 OUT 23-Apr-24 NOT PRESENT
1002 IN 23-Apr-24 NOT PRESENT
1002 OUT 23-Apr-24 NOT PRESENT
1000 OUT 24-Apr-24 17:00 PRESENT
1002 IN 24-Apr-24 08:00 PRESENT
1000 IN 24-Apr-24 08:00 PRESENT
1002 OUT 24-Apr-24 17:00 PRESENT

MASTERID2

ID2 NAMEID2 POSITION
1000 JACK STAFF
1001 ROY OPERATOR
1002 KEN STAFF
1003 REY OPERATOR

PERIOD

PERIODNAME STARTDATE ENDDATE
FIRST 22-Apr-24 25-Apr-24
SECOND 22-May-24 25-May-24

已确定的结果

但我想基于每个时期

ID2 NAMEID2 INOUT DATEABSEN TIME STATUS
1000 JACK IN 22-Apr-24 08:00 PRESENT
1000 JACK OUT 22-Apr-24 17:00 PRESENT
1002 KEN IN 22-Apr-24 08:00 PRESENT
1002 KEN OUT 22-Apr-24 17:00 PRESENT
1000 JACK IN 23-Apr-24 NOT PRESENT
1000 JACK OUT 23-Apr-24 NOT PRESENT
1002 KEN IN 23-Apr-24 NOT PRESENT
1002 KEN OUT 23-Apr-24 NOT PRESENT
1000 JACK IN 24-Apr-24 08:00 PRESENT
1000 JACK OUT 24-Apr-24 17:00 PRESENT
1002 KEN IN 24-Apr-24 08:00 PRESENT
1002 KEN OUT 24-Apr-24 17:00 PRESENT
1000 JACK IN 25-Apr-24 08:00 PRESENT
1000 JACK OUT 25-Apr-24 17:00 PRESENT
1002 KEN IN 25-Apr-24 08:00 PRESENT
1002 KEN OUT 25-Apr-24 17:00 PRESENT
1000 JACK IN 22-May-24 08:00 PRESENT
1000 JACK OUT 22-May-24 17:00 PRESENT
1002 KEN IN 22-May-24 08:00 PRESENT
1002 KEN OUT 22-May-24 17:00 PRESENT
1000 JACK IN 23-May-24 08:00 PRESENT
1000 JACK OUT 23-May-24
1002 KEN IN 23-May-24
1002 KEN OUT 23-May-24
1000 JACK IN 24-May-24
1000 JACK OUT 24-May-24
1002 KEN IN 24-May-24
1002 KEN OUT 24-May-24
1000 JACK IN 25-May-24
1000 JACK OUT 25-May-24
1002 KEN IN 25-May-24
1002 KEN OUT 25-May-24

推荐答案

我想我会通过一些奇特的循环来构建列表,但您可以接近SQL.

首先创建一个表或查询,返回10个名为TEN的数字:

SELECT DISTINCT [Id] Mod 10 AS Factor
FROM MSysObjects
WHERE MSysObjects.Id > 0

以及具有一个字段INOUT和两个记录的INOUT表:

IN  
OUT

接下来,创建UNION查询,ALLABSEN:

SELECT 
    ID2, INOUT, DATEABSEN, [TIME], STATUS
FROM 
    ABSEN
UNION 
SELECT 
    ID2, INOUT, DATEABSEN, [TIME], STATUS
FROM 
    HELPERABSEN

以及一个Cartesian查询ALLDATES,用于生成所有日期:

SELECT 
    PERIOD.PERIODNAME, [Factor]+[STARTDATE] AS [DATE]
FROM 
    PERIOD, 
    TEN
WHERE 
    [Factor]+[STARTDATE] Between [STARTDATE] And [ENDDATE]
ORDER BY 
    [Factor]+[STARTDATE]

还有一个Cartesian查询ALLID2DATES,用于返回所有可能的条目:

SELECT 
    MASTERID2.ID2, MASTERID2.NAMEID2, INOUT.INOUT, ALLDATES.Date
FROM 
    MASTERID2, 
    ALLDATES, 
    INOUT
WHERE
    MASTERID2.POSITION = 'STAFF'
ORDER BY 
    ALLDATES.Date, MASTERID2.ID2, INOUT.INOUT;

最后,您可以组装输出查询ID2ALLABSEN:

SELECT 
    ALLID2DATES.ID2, ALLID2DATES.NAMEID2, ALLID2DATES.INOUT, ALLID2DATES.DATE, ALLABSEN.TIME, ALLABSEN.STATUS
FROM 
    ALLID2DATES 
LEFT JOIN 
    ALLABSEN 
    ON (ALLID2DATES.DATE = ALLABSEN.DATEABSEN) AND (ALLID2DATES.INOUT = ALLABSEN.INOUT) AND (ALLID2DATES.ID2 = ALLABSEN.ID2)
ORDER BY 
    ALLID2DATES.DATE, ALLID2DATES.ID2, ALLID2DATES.INOUT, [DATE]+[ALLABSEN].[TIME]

输出:

enter image description here

Sql相关问答推荐

当编号和版本的唯一状态更改时报告

SQL查询以创建手头的流动余额?

如何根据SQL中的列条件获取下一个时间戳?

如何在T—SQL中找到值更改之前的日期?

基于时间的SQL聚合

如何从多行数据中获取一行合并数据?

将主表与历史表连接以获取主表的当前汇率以及历史表中的上一个和最后一个汇率

如何在presto/SQL中使用两个数组列创建(分解)单独的行

如何利用单列历史SQLsnowflake获得合并结果

UPDATE查询中的乐观锁

NULL-生成的列中连接的字符串的输入

找到最新的连线

在SQL中将项分配给容器

在 Postgres 中将结果按几十年划分

使用 Oracle SQL Developer 将不同的列值转换为列会导致错误 ORA-01489

group by 并根据同表中其他列的某些条件获取 group by 中的某一列值

如何在 SQL Server 中解决这个复杂的窗口查询?

如何在 ClickHouse SQL 中使用 CTE 将邻居语句中的数字作为偏移量传递?

使用 PL/PGSQL 函数 Select 返回多条记录

使用SQL中另一个表的查询结果在表中查找记录