我正在SQL Server Management Studio中工作,所以我想这是Microsoft SQL Server T-SQL问题。
现实情况是这样的:我有多个员工在多个位置工作,并且每个位置都有“ time in”和“ time out”记录。我已经为每个时间间隔创建了一个唯一的“班次ID”,并根据员工,日期和位置加入了与我的主要员工相匹配的其他员工的班次,或者将我与其他所有人进行比较的班次。
此外,我编写了一个查询,将每个“其他雇员”的特定重叠时间间隔与梯形失真拉在一起。对于一个班次,时间轴如下所示:
Key Emp. | 9AM------------------------6PM
Emp. A | 9AM------------------------6PM
Emp. B | 12PM-------4PM
因此可以进行真正的“受控”比较的离散时间段是:
最终目标是提取在该时间段内发生的每个员工的所有活动(在单独的表中组织为带有日期时间戳的事件),并比较每个相关员工的总计。因此,每个时间范围都将有一个单独的“计数(事件)”总计,仅受如上所述共享时间间隔的员工的影响。
目前,我的数据是这样组织的:
密钥和其他雇员的“输入”和“输出”列存储为TIMESTAMP;在我的示例中,“ 1 / 1,6PM”只是节省空间的糟糕方法。请在这篇文章的结尾查看我的消耗数据。 SSMS似乎并不在乎我是否拥有超过TIMESTAMP列,并将它们都视为DATETIME:
Key_ShiftID| Key In | Key Out | Oth_Emp_ShiftID | Oth_Emp_In | Oth_Emp_Out
K 1/1,9AM 1/1,6PM A 1/1,9AM 1/1,6PM
K 1/1,9AM 1/1,6PM B 1/1,12PM 1/1,4PM
其中Shift ID(Key_ShiftID和Oth_Emp_ShiftID)是唯一的字符串,并且时间间隔由两列(Key_In和Key_Out + Oth_Emp_In和Oth_Emp_Out)定义为日期时间/时间戳。我正在寻找可以比较员工活动的离散时间,该时间在单独的表中,每个事件都有一个独特的日期时间,如前所述。因此,我认为结束数据看起来像这样:
Key_ShiftID| Key_In | Key_Out | Oth_Emp_ShiftID | Oth_Emp_In | Oth_Emp_Out
K 1/1,9AM 1/1,6PM A 1/1,12PM 1/1,4PM
K 1/1,9AM 1/1,6PM B 1/1,12PM 1/1,4PM
K 1/1,9AM 1/1,6PM A 1/1,9AM 1/1,12PM
K 1/1,9AM 1/1,6PM A 1/1,4PM 1/1,6PM
这样我就可以通过ShiftID将上面的表加入到我的活动表中,并为每个相关员工引入计数(事件)
where event_datetime >= Oth_Emp_In and event_datetime <= Oth_Emp_Out
此外,如前所述,我已经编写了一个查询,以减少非关键员工的轮班以仅反映他们与关键员工重叠的时间间隔,因此Other_Emp_In将始终大于或等于键入时间,Other_Emp_Out将始终小于或等于键入时间。
先谢谢了。我一直在研究和解决这个问题大约2天。
这里是一键移位的示例数据(不是上面的确切示例):
此外,SQL Server似乎并不在乎我是否拥有超过TIMESTAMP列,并将它们都视为DATETIME。
CREATE TABLE "sample_data"
(
"Employee" INT,
"Key_ShiftID" TEXT,
"Key_In" TIMESTAMP,
"Key_Out" TIMESTAMP,
"Other_Emp_ShiftID" TEXT,
"Other_Emp_In" TIMESTAMP,
"Other_Emp_Out" TIMESTAMP,
"overlap_min" TIMESTAMP,
"overlap_max" TIMESTAMP
);
INSERT INTO "sample_data"
VALUES (900, '545BD826-0C9A-408B-BE9F-4C3D7D307948', '2016-09-27 14:15:00', '2016-09-27 21:45:00', '035FA1C1-B469-44EB-B5B4-5B6948574464', '2016-09-27 08:45:00', '2016-09-27 16:15:00', '2016-09-27 14:15:00', '2016-09-27 16:15:00'),
(78, '545BD826-0C9A-408B-BE9F-4C3D7D307948', '2016-09-27 14:15:00', '2016-09-27 21:45:00', '74035838-FD07-4F8D-8AC4-F6407AC786D9', '2016-09-27 18:00:00', '2016-09-27 21:15:00', '2016-09-27 18:00:00', '2016-09-27 21:15:00'),
(900, '545BD826-0C9A-408B-BE9F-4C3D7D307948', '2016-09-27 14:15:00', '2016-09-27 21:45:00', 'D7E9ADCD-8631-476D-B69F-00626F0E4B06', '2016-09-27 16:45:00', '2016-09-27 21:45:00', '2016-09-27 16:45:00', '2016-09-27 21:45:00');
答案 0 :(得分:0)
欢迎使用StackOverflow。将来,请尝试包含一些易消耗的示例数据,例如我在下面的解决方案中包含的数据。
这是一个有趣的小问题。对于这种情况,我利用了利用ngrams8K的patExtract8K函数。这是一个如何使用PatExtract的示例;在这里,我从一个字符串中提取钱:
import { validationMixin } from 'vuelidate';
import { required } from 'vuelidate/lib/validators';
var url = "https://bc-only-rates-trimakas.c9users.io";
export default {
mixins: [validationMixin],
validations: {
seller_id: { required }
},
props: ["amazonCredsArray"],
computed:{
sellerIdErrors () {
const errors = []
if (!this.$v.seller_id.$dirty) return errors
!this.$v.seller_id.checked && errors.push('Please provide us your seller id')
return errors
},
},
结果:
SELECT p.*
FROM dbo.patextract8K('Pay me $50.17 now or $1000 later!','[^$0-9.]') AS p;
现在要解决您的问题:
itemNumber itemIndex itemLength item
----------- ---------- ----------- --------
1 8 6 $50.17
2 22 5 $1000
结果:
-- Easily consumable sample data
DECLARE @table TABLE (shiftId VARCHAR(2), empKey VARCHAR(5), workDuration VARCHAR(100));
INSERT @table(shiftId,empKey,workDuration)
VALUES
('K','A','12PM - 4PM'),
('K','B','12PM - 4PM'),
('K','A','9AM - 12PM'),
('K','A','4PM - 6PM');
-- Solution
SELECT
shiftId = f.shiftId,
KeyIn = '1/1,'+REPLACE(CONVERT(VARCHAR(10),
MIN(CAST(f.c1 AS TIME)) OVER (),100),':00',''),
KeyOut = '1/1,'+REPLACE(CONVERT(VARCHAR(10),
MAX(CAST(f.c2 AS TIME)) OVER (),100),':00',''),
empShift = f.empKey,
othEmpIn = '1/1,'+f.c1,
othEmpOut = '1/1,'+f.c2
FROM
(
SELECT t.shiftId, t.empKey, t.workDuration,
c1 = MAX(CASE p.itemNumber WHEN 1 THEN p.item END),
c2 = MAX(CASE p.itemNumber WHEN 2 THEN p.item END)
FROM @table AS t
CROSS APPLY dbo.patExtract8k(t.workDuration, '[^0-9APM]') AS p
CROSS APPLY (VALUES(CAST(p.item AS TIME))) AS tm(N)
GROUP BY t.shiftId, t.empKey, t.workDuration
) AS f;
请注意,我不知道“ 1/1”来自何处,所以我只是对其进行了硬编码。
这是我的基本功能。所有这些都对以很少的代码有效地解决各种各样的SQL问题很有帮助。
shiftId KeyIn KeyOut empShift othEmpIn othEmpOut
------- ---------- ------------ -------- ------------ ------------
K 1/1,9AM 1/1,6PM A 1/1,12PM 1/1,4PM
K 1/1,9AM 1/1,6PM A 1/1,4PM 1/1,6PM
K 1/1,9AM 1/1,6PM A 1/1,9AM 1/1,12PM
K 1/1,9AM 1/1,6PM B 1/1,12PM 1/1,4PM