Sql server 如何仅显示日期可用的女佣?SQL SERVER

Sql server 如何仅显示日期可用的女佣?SQL SERVER,sql-server,Sql Server,我有一个存储女佣详细信息的女佣表和一个存储约会详细信息的约会表,例如每个约会都分配给哪个女佣,因此约会表中包含女佣id。如何仅显示尚未分配给任何工作的女佣(可用女佣)和女佣可用的日期 服务员 餐桌预约 我所做的一切 SELECT Maid_ID FROM Maid EXCEPT SELECT WO_MaidName FROM Appointments 给定用户输入的2019-06-03,我希望得到以下结果: Maid_ID Available Date ---------------

我有一个存储女佣详细信息的女佣表和一个存储约会详细信息的约会表,例如每个约会都分配给哪个女佣,因此约会表中包含女佣id。如何仅显示尚未分配给任何工作的女佣(可用女佣)和女佣可用的日期

服务员

餐桌预约

我所做的一切

SELECT Maid_ID FROM Maid
EXCEPT
SELECT WO_MaidName FROM Appointments
给定用户输入的
2019-06-03
,我希望得到以下结果:

Maid_ID    Available Date
--------------------------
   2        2019-06-03
   3        2019-06-03
   5        2019-06-03
你试过这个吗

SELECT Maid_ID 
FROM Maid LEFT JOIN Appointments
    ON Maid.Maid_ID = Appointments.WO_MaidName
WHERE Appointments.WO_MaidName IS NULL
此查询返回Maid表中的所有行,而不返回约会表中关联的任何行

SELECT Maid_ID
FROM Maid
WHERE Maid_ID NOT IN (
    SELECT WO_MaidName
    FROM Appointments
    WHERE Appointment_DateTime BETWEEN '20190603' AND '20190604')

第二个查询返回where子句中日期之间没有约会的所有Maid行。

这可能没有优化,但它可以工作

CREATE TABLE #TEMP 
    (
        Maid_Id INT,
        AppointmentDateTime DATETIME
    )

DECLARE db_cursor CURSOR FOR SELECT distinct Appointment.AppointmentDateTime FROM Appointment; 
DECLARE @date datetime;
OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO @date;
WHILE @@FETCH_STATUS = 0  
BEGIN  
        INSERT INTO #TEMP (Maid_Id, AppointmentDateTime)
        SELECT M.Maid_Id, @date FROM Maid M
        WHERE M.Maid_Id NOT IN (
            SELECT a.Maid_Id FROM Appointment a
            WHERE A.AppointmentDateTime = @date
        )

       FETCH NEXT FROM db_cursor INTO @date;
END;
CLOSE db_cursor;
DEALLOCATE db_cursor;

SELECT T.Maid_Id, M.Maid_Name, T.AppointmentDateTime FROM #TEMP T
INNER JOIN Maid M ON T.Maid_Id = M.Maid_Id
ORDER BY AppointmentDateTime

DROP TABLE #TEMP

另一种解决方案是使用特定日期,并在每个日期根据需要调用它。 首先,在
SqlServer
中添加一个
表值函数,如下所示:

CREATE FUNCTION [dbo].[MyFunction]
(   
    @date datetime
)
RETURNS TABLE 
AS
RETURN 
(
    SELECT M.Maid_Id FROM Maid M
            WHERE M.Maid_Id NOT IN (
                SELECT a.Maid_Id FROM Appointment a
                WHERE A.AppointmentDateTime = @date
            )
)
然后这样称呼它:

DECLARE @Date DATETIME = '2019-05-15 00:00:00.000'; // Put the date you want
SELECT m.Maid_Id, m.Maid_Name, @Date FROM Maid M
INNER JOIN [dbo].[MyFunction](@Date) F ON M.Maid_Id = F.Maid_Id

最后,请尝试以下方法:

-- Create a Temporary table for keep Maid_Id and AppointmentDateTime
CREATE TABLE #TEMP 
    (
        Maid_Id INT,
        AppointmentDateTime DATETIME
    )


-- Select all AppointmentDateTime are present in Appointment
DECLARE db_cursor CURSOR FOR SELECT distinct Appointment.AppointmentDateTime FROM Appointment; 


-- Iterate them to insert them into the temporary table
DECLARE @date datetime;
OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO @date;
WHILE @@FETCH_STATUS = 0  
BEGIN  
        INSERT INTO #TEMP (Maid_Id, AppointmentDateTime)
        SELECT M.Maid_Id, @date FROM Maid M
        WHERE M.Maid_Id NOT IN (
            SELECT a.Maid_Id FROM Appointment a
            WHERE A.AppointmentDateTime = @date
        )

       FETCH NEXT FROM db_cursor INTO @date;
END;
CLOSE db_cursor;
DEALLOCATE db_cursor;


-- Create another temporary table to keep all the dates we need
DECLARE @MinDate DATE = '2019-05-10',
        @MaxDate DATE = '2019-07-24';
CREATE TABLE #DATES 
    (
        [DATE] DATETIME
    )


-- Create a range of dates that we need and insert them in the temporary table. It can cover a wide range of dates like 2000-01-01 to Now
INSERT INTO #DATES
SELECT  TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1)
        Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY A.OBJECT_ID) - 1, @MinDate)
FROM    SYS.ALL_OBJECTS A
CROSS JOIN SYS.ALL_OBJECTS B;


-- Union all the data
SELECT M.Maid_Id, M.Maid_Name, CONVERT(NVARCHAR(10), T.AppointmentDateTime, 120) [date] FROM #TEMP T
INNER JOIN Maid M ON T.Maid_Id = M.Maid_Id
UNION
SELECT null, 'All People Are Free', CONVERT(NVARCHAR(10), [DATE], 120) FROM #DATES
ORDER BY [date]


DROP TABLE #TEMP
DROP TABLE #DATES
结果如下:

CREATE FUNCTION [dbo].[MyFunction]
(   
    @date datetime
)
RETURNS TABLE 
AS
RETURN 
(
    SELECT M.Maid_Id FROM Maid M
            WHERE M.Maid_Id NOT IN (
                SELECT a.Maid_Id FROM Appointment a
                WHERE A.AppointmentDateTime = @date
            )
)

您有错误吗?除了这里好,我看不出有什么错误。@ArnaudPeralta,没有错误,但结果不符合我的需要。我希望它能显示女佣以及女佣免费或有空的日期。我之前的查询只是显示尚未分配给约会的女佣id。那么,女佣2的可用日期是什么时候?每个日期?为什么列
Maid\u Age
N/VARCHAR
数据类型而不是
INT
?让我给出一个场景。在6月3日的桌上约会中,id为1和4的女佣已被分配到约会。id为2、3和5的女佣在6月3日是免费的。因此,现在我想显示女佣2、3和5以及6月3日的日期。我如何才能做到这一点?我还想显示女佣的出生日期available@testtest可用日期在哪里?@testtest哪个表是日期?让我给出一个场景。在6月3日的桌上约会中,id为1和4的女佣已被分配到约会。id为2、3和5的女佣在6月3日是免费的。因此,现在我想显示女佣2、3和5以及6月3日的日期。我该怎么做?@testtest我用一个新的查询编辑了答案,这是你想要的吗?我尝试了你的查询,结果与你的不一样,因为它也显示了时间。我想和你的一模一样。有什么问题吗?请发送您的
表格模式
数据
以及您的结果。关于我的查询,首先,它生成一个临时表。其次,它检索所有日期
selectdistinct Appointment.AppointmentDateTime FROM Appointment'。然后用
Cursor`迭代它们(Maid_Id和AppointmentDate),并将它们插入临时表中。最后,加入临时表与女佣。表上面的查询只显示约会表中已有的日期。如何进行查询以同时显示不在表中的日期?例如,6月13日将显示所有maid 1、2、3、4和5,因为没有人被分配到6月13日的任命。应显示哪些日期?例如,从今天起的最短日期开始?或者别的什么?我不想要具体的日期。我想让它显示所有的日期