如何在集合中思考

时间:2013-10-04 15:24:14

标签: sql tsql loops foreach sql-server-2008-r2

我的公司有程序,员工,客户和活动。我们希望为每个计划中的每个员工审核两个随机客户事件。

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

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会很酷。)

其他人发布了类似的问题。我发布这个是因为它是如何在集合中思考的一个纯粹的例子。请帮我迭代一下。谢谢。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

我不是百分百肯定我已经了解了这些要求,但您可以根据自己的需要进行调整。我将它们理解为“对于每个员工/项目组合,随机抽取两个事件”。

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

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

更优雅。