Mysql 将所有房间与所有其他房间进行比较(笛卡尔乘积)
我有如下存储的考勤数据:Mysql 将所有房间与所有其他房间进行比较(笛卡尔乘积),mysql,Mysql,我有如下存储的考勤数据: Building | Room | Date | Morning | Evening ------------------------------------------ BuildA A1 1 10 15 BuildA A1 2 20 35 BuildA A1 3 30 15 BuildA A2 1 60
Building | Room | Date | Morning | Evening
------------------------------------------
BuildA A1 1 10 15
BuildA A1 2 20 35
BuildA A1 3 30 15
BuildA A2 1 60 30
BuildA A2 2 30 10
BuildA A2 3 40 20
BuildB B1 1 20 25
BuildB B1 2 10 35
BuildB B1 3 30 10
BuildB B2 1 15 25
BuildB B2 2 25 35
BuildB B2 3 25 15
Building | Room | Date | Morning | Evening | MorningDiff | EveningDiff
-----------------------------------------------------------------------
BuildA A1 1 10 15 0 0
BuildA A1 2 20 35 10 20
BuildA A1 3 30 15 10 -20
BuildA A2 1 60 30 0 0
BuildA A2 2 30 10 -30 -20
BuildA A2 3 40 20 10 10
BuildB B1 1 20 25 0 0
BuildB B1 2 10 35 -10 10
BuildB B1 3 30 10 20 -25
BuildB B2 1 15 25 0 0
BuildB B2 2 25 35 10 10
BuildB B2 3 25 15 0 -20
然后,我需要查看每个房间每天每个时间的出勤率与前一天的出勤率的差异。结果如下所示:
Building | Room | Date | Morning | Evening
------------------------------------------
BuildA A1 1 10 15
BuildA A1 2 20 35
BuildA A1 3 30 15
BuildA A2 1 60 30
BuildA A2 2 30 10
BuildA A2 3 40 20
BuildB B1 1 20 25
BuildB B1 2 10 35
BuildB B1 3 30 10
BuildB B2 1 15 25
BuildB B2 2 25 35
BuildB B2 3 25 15
Building | Room | Date | Morning | Evening | MorningDiff | EveningDiff
-----------------------------------------------------------------------
BuildA A1 1 10 15 0 0
BuildA A1 2 20 35 10 20
BuildA A1 3 30 15 10 -20
BuildA A2 1 60 30 0 0
BuildA A2 2 30 10 -30 -20
BuildA A2 3 40 20 10 10
BuildB B1 1 20 25 0 0
BuildB B1 2 10 35 -10 10
BuildB B1 3 30 10 20 -25
BuildB B2 1 15 25 0 0
BuildB B2 2 25 35 10 10
BuildB B2 3 25 15 0 -20
通过此查询,我可以完成上一步:
select t.*,
COALESCE((`morning` -
(select `morning`
from data t2
where t2.date < t.date
and t2.room = t.room
order by t2.date desc
limit 1 )) ,0)
as MorningDiff,
COALESCE((`evening` -
(select `evening`
from data t2
where t2.date < t.date
and t2.room = t.room
order by t2.date desc
limit 1 )) ,0)
as EveningDiff
from data t
order by room,date asc;
获取日期差异的原因是为了查看出席人数是否比前一天增加或减少。实际上,我们并不关心差异的实际数字,我们只关心它是上升还是下降
OccurranceCount字段-如果某个房间的出勤率在某一天上升/下降,我们将尝试查看第二天是否有其他房间的出勤率上升/下降。然后,此字段用于计算room2一天上升/下降的次数以及room1第二天上升/下降的次数。因此,如果我们以第一排为例,它表明A1房间的早上出勤率上升了1倍,而A2房间的早上出勤率在前一天的3天内上升了1倍
Room1DirectionCount/Room2DirectionCount字段-这些字段仅显示每个房间每个方向发生的时间。因此,如果在100天的时间内,如果A1房间的出勤率增加了60倍,则计数将为60
由于我将所有房间相互比较,我尝试进行交叉连接以形成笛卡尔积,但我无法确定如何正确进行连接,因此它引用了另一个房间的前一天
我不知道为什么这个问题被标记为与数据透视表有关的问题的重复?我不相信这个问题可以用这个答案来回答。我很难理解您在第二个预期输出中的一些专栏的含义。然而,不管怎样,这里有一些示例和演示可能会帮助您 如果您使用的是MySQL 8.0,那么可以使用wonderful访问与当前行相关的行。以下查询返回您的第一个预期输出,尽管在没有前一天的情况下,返回的是NULL而不是0,以区别于频繁光顾与前一天相同的情况:
select
a.*,
morning - lag(a.morning) over (partition by a.building, a.room order by a.date) morning_diff,
evening - lag(a.evening) over (partition by a.building, a.room order by a.date) evening_diff
from attendance a
order by a.building, a.room, a.date
对于较旧版本的mysql,您可以使用自左连接访问前一行:
select
a.*,
a.morning - a1.morning morning_diff,
a.evening - a1.evening evening_diff
from
attendance a
left join attendance a1
on a1.building = a.building and a1.room = a.room and a1.date = a.date - 1
order by a.building, a.room, a.date
看
一旦您有了一个返回考勤差异的查询,您就可以很容易地看到它在外部查询中是上升了还是下降了。例如,考虑:
select t.*,
case
when morning_diff is null then 'Unknown'
when morning_diff = 0 then 'Even'
when morning_diff > 0 then 'Up'
when morning_diff < 0 then 'Down'
end morning_direction,
case
when evening_diff is null then 'Unknown'
when evening_diff = 0 then 'Even'
when evening_diff > 0 then 'Up'
when evening_diff < 0 then 'Down'
end evening_direction
from (
select
a.*,
morning - lag(a.morning) over (partition by a.building, a.room order by a.date) morning_diff,
evening - lag(a.evening) over (partition by a.building, a.room order by a.date) evening_diff
from attendance a
) t
order by t.building, t.room, t.date;
请参阅。我不能100%确定我是否理解您的问题,并且没有足够的样本数据/预期输出来确定,但我认为此查询将为您提供所需的结果。它使用了两个CTE:一个用于获取每个建筑/房间/日期/时间组合的差异,第二个用于对RoomDirectionCount列的差异求和,然后仅对分组行进行计数以获得OccurrenceCount列 输出太长,无法包含在此处,但我已创建了一个。交替
注意,我使用了WHERE a1.diff IS NOT NULL子句来排除第一天的结果,你可能会在atdiff表中合并diff的计算,然后不使用它。可能的重复肯定不是透视表问题。你使用的是什么版本的MySQL?你有兴趣比较所有建筑物中的所有房间还是同一建筑物中的房间?@Nick。我正在使用MySQL 8.0。所有建筑物中的所有房间。谢谢。非常感谢这个功能!对不起,我知道这让人困惑。我们有大楼每个房间的基本早晚出勤数据。我们的目标是观察一个房间的出勤率何时上升/下降,第二天另一个房间的出勤率是否上升/下降。因此,如果A房间晚上的出勤率上升,而第二天B房间早上的出勤率下降,我们想知道在某个时间段内发生了多少次。我们想运行所有可能的房间组合,看看房间出勤率之间是否存在相关性。谢谢您的回复!很抱歉,你碰巧有这把小提琴。提供的fiddle链接似乎不正确对不起,忘记按dbfiddle上的Update。我现在已经更正了链接。不管怎么说,很高兴它似乎奏效了。