我有一张表,其中包含用户提交的多条记录。在每个记录中都有一个名为COMPLETE的字段,用于指示记录是否完全完成。
我需要一种方法来获取用户的最新记录,其中COMPLETE为0,LOCATION,DATE是相同的,并且在COMPLETE为1的情况下不存在其他记录。在每个记录中还有其他字段,如Type,AMOUNT,Total等等。即使USER,LOCATION和DATE相同,它们也可能不同。
有一个SUB_DATE字段和ID字段,表示提交的日期和自动递增的ID号。这是表格:
ID NAME LOCATION DATE COMPLETE SUB_DATE TYPE1 AMOUNT1 TYPE2 AMOUNT2 TOTAL
1 user1 loc1 2017-09-15 1 2017-09-10 Food 12.25 Hotel 65.54 77.79
2 user1 loc1 2017-09-15 0 2017-09-11 Food 12.25 NULL 0 12.25
3 user1 loc2 2017-08-13 0 2017-09-05 Flight 140 Food 5 145.00
4 user1 loc2 2017-08-13 0 2017-09-10 Flight 140 NULL 0 140
5 user1 loc3 2017-07-14 0 2017-07-15 Taxi 25 NULL 0 25
6 user1 loc3 2017-08-25 1 2017-08-26 Food 45 NULL 0 45
我想要检索的结果是ID 4,因为SUB_DATE后面是ID 3.它具有相同的名称,位置和日期信息,并且没有带有1值的COMPLETE。
我还想检索ID 5,因为它是用户,位置,日期和完成的最新记录是0.
如果你能解释一下你的答案,帮助我理解解决方案中发生的事情,我将不胜感激。
答案 0 :(得分:0)
不确定我是否完全理解但是试试这个
SELECT *
FROM (
SELECT *,
MAX(CONVERT(INT,COMPLETE)) OVER (PARTITION BY NAME,LOCATION,DATE) AS CompleteForNameLocationAndDate,
MAX(SUB_DATE) OVER (PARTITION BY NAME, LOCATION, DATE) AS LastSubDate
FROM your_table t
) a
WHERE CompleteForNameLocationAndDate = 0 AND
SUB_DATE = LastSubDate
所以我们在这里做了什么:
首先,如果您只在Management Studio中运行内部查询,您将看到它的作用:
第一个max函数将按照每个唯一的Name,Location,Date设置对表中的数据进行分区。 对于您的数据,ID 1& 2是第一个分区,3& 4是第二个分区,5是第3个分区,6是第4个分区。 因此,对于每个分区,它将在完整列中获得最大值。因此,任何具有1作为其最大值的分区都已完成。
另请注意,转换功能。这是因为COMPLETE的数据类型为BIT(1或0),并且max函数不适用于该数据类型。因此我们转换为INT。如果您的COMPLETE列是INT类型,则可以进行转换。
第二个max函数再次按唯一名称,位置和日期进行分区,但这次我们得到max_sub日期,它给出了名称,位置,日期的最新记录的日期
因此我们将该查询添加到派生表中,为简单起见,我们将其称为。我们需要这样做,因为SQL Server不允许在查询的WHERE子句中使用窗口函数。窗口函数是我们使用OVER关键字的函数。在理想的世界中,SQL会让我们做到
SELECT *,
MAX(CONVERT(INT,COMPLETE)) OVER (PARTITION BY NAME,LOCATION,DATE) AS CompleteForNameLocationAndDate,
MAX(SUB_DATE) OVER (PARTITION BY NAME, LOCATION, DATE) AS LastSubDate
FROM your)table t
WHERE MAX(CONVERT(INT,COMPLETE)) OVER (PARTITION BY NAME,LOCATION,DATE) = 0 AND
SUB_DATE = MAX(SUB_DATE) OVER (PARTITION BY NAME, LOCATION, DATE)
但它不允许它,所以我们必须使用派生表。
那么我们基本上从派生表Where
中选择所有内容CompleteForNameLocationAndDate = 0
哪些是名称,位置,日期分区没有标记为完整的记录。
然后我们进一步过滤,只询问每个分区的最新记录
SUB_DATE = LastSubDate
希望有道理,不确定你需要什么程度的细节?
作为一方,我会考虑重组您的表格(除非您已经简化以更好地解释此问题),如下所示:
(假设您的示例中的表格称为预订)
tblBooking
BookingID
PersonID
LocationID
Date
Complete
SubDate
tblPerson
PersonID
PersonName
tblLocation
LocationID
LocationName
tblType
TypeID
TypeName
tblBookingType
BookingTypeID
BookingID
TypeID
Amount
这样,如果您想在预订信息中添加Type3或Type4,则无需更改表格布局