Sql 在具有不同值的字段上连接
我正在尝试连接来自两个完全不同来源的数据。一个来源包含员工的日程信息,另一个来源跟踪他们实际工作的时间(比如他们实际吃午饭或休息的时间)。问题是,日程表程序将时间列为BREAK1、BREAK2、BREAK3和午餐,而跟踪程序只是将时间列为午餐和休息。我可以加入到数据中,很好地得到午餐,但是休息时间让我感到厌烦。如果我将BREAK1、BREAK2和BREAK3转换为“Break”,我会得到太多的线段,因为它将每个实例与其他实例匹配。有没有一种方法,任何人都可以想到连接这两条信息?多谢各位 编辑 根据您的要求,以下是一些示例数据: 这是预定时间:Sql 在具有不同值的字段上连接,sql,join,Sql,Join,我正在尝试连接来自两个完全不同来源的数据。一个来源包含员工的日程信息,另一个来源跟踪他们实际工作的时间(比如他们实际吃午饭或休息的时间)。问题是,日程表程序将时间列为BREAK1、BREAK2、BREAK3和午餐,而跟踪程序只是将时间列为午餐和休息。我可以加入到数据中,很好地得到午餐,但是休息时间让我感到厌烦。如果我将BREAK1、BREAK2和BREAK3转换为“Break”,我会得到太多的线段,因为它将每个实例与其他实例匹配。有没有一种方法,任何人都可以想到连接这两条信息?多谢各位 编辑 根
EMP_ID NOM_DATE SEG_CODE START_MOMENT STOP_MOMENT
626009 26-Sep-13 BREAK2 9/26/13 5:00 PM 9/26/13 5:15 PM
625650 26-Sep-13 BREAK2 9/26/13 4:30 PM 9/26/13 4:45 PM
638815 26-Sep-13 BREAK2 9/26/13 4:00 PM 9/26/13 4:15 PM
621649 26-Sep-13 BREAK2 9/26/13 3:30 PM 9/26/13 3:45 PM
567005 26-Sep-13 BREAK2 9/26/13 3:30 PM 9/26/13 3:45 PM
626009 26-Sep-13 LUNCH 9/26/13 2:30 PM 9/26/13 3:30 PM
625650 26-Sep-13 LUNCH 9/26/13 1:30 PM 9/26/13 2:30 PM
638815 26-Sep-13 LUNCH 9/26/13 1:30 PM 9/26/13 2:30 PM
621649 26-Sep-13 LUNCH 9/26/13 12:30 PM 9/26/13 1:30 PM
567005 26-Sep-13 LUNCH 9/26/13 12:30 PM 9/26/13 1:30 PM
626009 26-Sep-13 BREAK1 9/26/13 11:45 AM 9/26/13 12:00 PM
625650 26-Sep-13 BREAK1 9/26/13 11:30 AM 9/26/13 11:45 AM
638815 26-Sep-13 BREAK1 9/26/13 11:45 AM 9/26/13 12:00 PM
621649 26-Sep-13 BREAK1 9/26/13 9:30 AM 9/26/13 9:45 AM
567005 26-Sep-13 BREAK1 9/26/13 9:30 AM 9/26/13 9:45 AM
这是实际时间
EMP_ID Seg_Code Start_Time Stop_Time
625650 Break 9/26/2013 17:54 9/26/2013 17:55
567005 Break 9/26/2013 14:56 9/26/2013 14:59
567005 Break 9/26/2013 15:32 9/26/2013 15:44
638815 Break 9/26/2013 16:34 9/26/2013 16:47
567005 Break 9/26/2013 10:08 9/26/2013 10:21
626009 Break 9/26/2013 17:01 9/26/2013 17:15
625650 Break 9/26/2013 11:31 9/26/2013 11:45
626009 Break 9/26/2013 11:52 9/26/2013 12:07
621649 Break 9/26/2013 9:34 9/26/2013 9:48
621649 Break 9/26/2013 15:31 9/26/2013 15:45
638815 Break 9/26/2013 11:46 9/26/2013 12:02
625650 Break 9/26/2013 16:35 9/26/2013 16:51
567005 Lunch 9/26/2013 12:31 9/26/2013 13:29
625650 Lunch 9/26/2013 13:31 9/26/2013 14:30
626009 Lunch 9/26/2013 14:31 9/26/2013 15:30
638815 Lunch 9/26/2013 13:31 9/26/2013 14:30
621649 Lunch 9/26/2013 12:31 9/26/2013 13:30
我试图得到他们计划的时间和他们实际休息的时间之间的差异(以分钟为单位)。一个正确的例子是:
Badge Seg_Code Scheduled Start Scheduled Stop Actual Start Actual Stop Difference Seg_Duration
192329 Lunch 9/26/13 8:15 AM 9/26/13 9:15 AM 9/26/2013 8:18:27 AM 9/26/2013 9:17:59 AM 3 0:00:59:32
再次感谢虽然在频繁运行的查询中通常不是一个好主意,但您可以在连接条件中使用字符串函数。例如,在MySQL中,它将如下所示:
CREATE TABLE test1 (
worktype VARCHAR(20)
);
INSERT INTO test1 VALUES ('BREAK1');
INSERT INTO test1 VALUES ('BREAK2');
CREATE TABLE test2 (
worktype VARCHAR(20)
);
INSERT INTO test2 VALUES ('Break');
SELECT t1.worktype 't1', t2.worktype 't2'
FROM test1 t1
JOIN test2 t2 ON LEFT(t1.worktype, LENGTH(t2.worktype)) = LOWER(t2.worktype);
根据您的应用程序,这可能是合理的—例如,如果您每周运行一次批处理作业,以便从您无法控制的源复制数据
至于你的第二个问题:如果表中没有其他可以在连接中使用的数据,那么无法解决“Break”与“BREAK1”和“BREAK2”等连接的问题——换句话说,熵或信息密度太低了。你必须自己想出一个“平局断路器”来决定你想显示哪一行(“断开1行”,“断开2行”)。例如,您可以使用以下规则:“始终使用BREAK1而不是BREAK2”。您的帖子中没有足够的信息为您制定规则。假设SQL Server:
;WITH Actual_Ranked AS
(
SELECT
ROWNUM = CASE Seg_Code
WHEN 'Break' THEN CAST(ROW_NUMBER() OVER (PARTITION BY EMP_ID, Seg_Code, CAST(Start_Time AS DATE) ORDER BY Start_Time) AS VARCHAR(1))
ELSE ''
END,
EMP_ID,
Seg_Code,
Start_Time,
Stop_Time
FROM
#Actual
)
SELECT
ISNULL(sched.EMP_ID, act.EMP_ID) AS Badge,
ISNULL(sched.SEG_CODE, (act.SEG_CODE + ROWNUM)) AS Seg_Code,
CONVERT(VARCHAR, sched.START_MOMENT, 22) AS [Scheduled Start],
CONVERT(VARCHAR, sched.STOP_MOMENT, 22) AS [Scheduled Stop],
CONVERT(VARCHAR, act.Start_Time, 22) AS [Actual Start],
CONVERT(VARCHAR, act.Stop_Time, 22) AS [Actual Stop],
DATEDIFF(minute, sched.START_MOMENT, act.Start_Time) AS [Difference]
FROM
#Scheduled sched
FULL JOIN Actual_Ranked act ON sched.EMP_ID = act.EMP_ID
AND sched.SEG_CODE = (act.SEG_CODE + ROWNUM);
根据需要替换表名
关键是我要得到中断的行号,并附加它以使连接工作
我没有加入Seg_Duration
以保持答案的简单性,但您可以通过查看的答案以您喜欢的格式显示持续时间
SQL Fiddle。在一天内的时间内排名?能否在SQL Fiddle中包含表结构和样本数据?然后给我们期望的产量,我们就可以帮你完成。@zimdanen-我不太清楚你在说什么?很抱歉没有说清楚。EMP_ID字段还用于确保每个来源的员工匹配正确。谢谢,谢谢你的回复。当我运行代码并更改表时,“计划开始”和“计划停止”列或“实际开始”和“实际停止”字段中都有空值。我认为这是因为出于某种原因,它正在将“实际”字段转换为1899年的日期。我已经尝试过修复它,但看不出到底是在哪里发生的。我想可能是演员。再次感谢。@Dantalion88:使用示例数据,有两行的
NULL
s,但它们仅位于计划开始
、计划停止
和差异
列中。我将组装一个SQLFIDLE来演示代码。如果您的数据不起作用,我需要查看它以帮助您修复它。@Dantalion88:添加了SQL FIDLE。请随意更改以包含您有问题的数据,以便我可以查看。谢谢您的帮助,我已经解决了。我给出了一些实际上已经“修正”了一点的样本数据。我添加了子查询,以将数据修改到代码中需要的位置,并且成功了。再次感谢!