2

我的公司有项目、员工、客户和活动。我们想为每个程序中的每个员工审计两个随机客户端事件。

我创建了一个查询来选择过去六个月在某个程序中发生过客户事件的所有员工。

SELECT TOP(2) 
    program_id, staff_id, client_id, event_date
FROM 
    events 
INNER JOIN 
    client ON events.client_id = client.client_id
WHERE 
    <blah, blah> --by date range, program, client showed up at event ...
ORDER BY 
    NEWID() --randomizes the top 2 picked from this set

现在,我需要对每个程序中的每个工作人员进行迭代。员工可以在多个项目中服务,在这种情况下,我们会为每个员工/项目组合审核两个客户事件。

结果应该是这样的:

program_id  staff_id    client_id   event_date

p1  12345   abc123  8/26/2013
            xyz123  5/16/2013
p1  23456   bcd123  7/26/2013
            wxy123  4/16/2013
p2  12345   cde123  9/26/2013
            xyz123  3/16/2013
p3  34567   efg123  7/26/2013
            uvw123  5/16/2013

(将其吐出到每个程序都有一个单独的选项卡的 xls 会很酷。)

其他人也发布了类似的问题。我发布这个是因为它是如何在集合中思考的一个纯粹的例子。请帮助我遍历该集合。谢谢你。

4

2 回答 2

0

我不是 100% 确定我已经理解了这些要求,但您肯定可以根据自己的需要进行调整。我将它们理解为“对于每个工作人员/程序组合,随机绘制两个事件”。

我首先计算可能的人员/程序组合。然后对于每个组合,我们要绘制两个随机事件:

WITH combinations AS (
 SELECT DISTINCT program_id, staff_id
 FROM events
)
SELECT e.*
FROM combinations c
CROSS APPLY (
 SELECT TOP 2 *
 FROM events e
 WHERE e.program_id = c.program_id AND e.staff_id = c.staff_id
 ORDER BY NEWID()
) e

CROSS APPLY表示“对于每个外部行(c在这种情况下从中绘制)将以下行连接到它”。

这是一个不同的版本:

SELECT *
FROM (
 SELECT *, ROW_NUMBER() OVER (PARTITION BY program_id, staff_id ORDER BY NEWID()) r
 FROM events e
) e
WHERE e.r <= 2

优雅得多。

于 2013-10-04T15:56:18.150 回答
0

我有一些建议,但不是一个完整的答案。我要做的一件事是在 SQL 中按 program_id 分组,这样您就可以看到每个程序都有它的员工。

这解决了您的最后一个问题 - 可以通过自连接来完成行的扁平化。

SELECT lt1.program_id  
    , lt1.staff_id    
    , lt1.client_id   
    , lt1.event_date
    , lt2.staff_id    
    , lt2.client_id   
    , lt2.event_date

FROM youLastTable lt1
    Join youLastTable on lt1.program_id = lt2.program_id

会产生这个:

p1  12345   abc123  8/26/2013   xyz123  5/16/2013
p1  23456   bcd123  7/26/2013   wxy123  4/16/2013
p2  12345   cde123  9/26/2013   xyz123  3/16/2013
p3  34567   efg123  7/26/2013   uvw123  5/16/2013

对于您的第一个问题,如何按组随机获取两行,尝试对值进行分组并让我知道它是否有效。例如:

SELECT TOP(2) 
    program_id, staff_id, client_id, event_date
FROM 
    events 
INNER JOIN 
    client ON events.client_id = client.client_id
WHERE 
    <blah, blah> --by date range, program, client showed up at event ...
GROUP BY  program_id -- and possibly, staff_id
ORDER BY 
    NEWID() --randomizes the top 2 picked from this set
于 2013-10-04T15:44:25.997 回答