如何选择具有一些共同值的两个不同行

时间:2015-02-21 11:44:41

标签: sql sql-server

我想通过选择行并在网页上显示来显示sql表中的路径

表:

**UCId  UCPre                         UCPost                        UCNext  Prob** 
UC01    User must be Registerd        User is Loggined sucessfully  UC02    0.5
UC01    User must be Registerd        User is Loggined sucessfully  UC05    0.5
UC02    User is Loggined sucessfully  User is added                 UC03    1
UC03    User is added                 File is added                 NULL    1
UC04    File is selected              File is deleted               NULL    1
UC05    User is Loggined sucessfully  User is deleted               NULL    1

我正在使用以下查询

select distinct UCId,UCNext,Prob from test  where UCNext <>'Null'

查询结果:

UCId    UCNext  Prob
UC01    UC02    0.5
UC01    UC05    0.5
UC02    UC03    1

Q1:现在我想选择UC01但是有两行从UC01开始如何随机选择行? Q2:如果选择行号1,UC01为Id,UC02为UCNext,我们在表中可以看到,UC02也有UC03,所以我想显示完整的路径

UC01-UCO 2-UC03

请帮帮忙?

1 个答案:

答案 0 :(得分:0)

您可以使用以下方法为每个UCid“分区”选择一个随机行:

select  *
from    (
        select  row_number() over (
                    partition by UCid
                    order by newid()) as rn
        ,       *
        from    YourTable
        ) sub1
where   rn = 1 -- Random row per UCid

在SQL中计算“路径”并不容易。一种方法是递归CTE。顶部寻找根源。 union all分隔CTE的顶部和递归部分。递归部分迭代到子节点,直到它到达叶节点。

; with  path as
        (
        select  UCId
        ,       UCNext
        ,       Prob
        ,       cast(UCId as varchar(max)) as path
        ,       UCNext as child_next
        from    dist_rows
        union all
        select  parent.UCId
        ,       parent.UCNext
        ,       parent.Prob
        ,       parent.path + '/' + child.UCid
        ,       child.UCNext
        from    path parent
        join    dist_rows child
        on      child.UCid = parent.child_next
        )

结合这两者,你得到:

; with  dist_rows as
        (
        select  *
        from    (
                select  row_number() over (
                            partition by UCid
                            order by newid()) as rn
                ,       *
                from    YourTable
                ) sub1
        where   rn = 1 -- Random row per UCid
        )
,       path as
        (
        select  UCId
        ,       UCNext
        ,       Prob
        ,       cast(UCId as varchar(max)) as path
        ,       UCNext as child_next
        from    dist_rows
        union all
        select  parent.UCId
        ,       parent.UCNext
        ,       parent.Prob
        ,       parent.path + '/' + child.UCid
        ,       child.UCNext
        from    path parent
        join    dist_rows child
        on      child.UCid = parent.child_next
        )
select  UCId
,       UCNext
,       Prob
,       path
from    path
where   child_next is null -- Only leafs
;

Example at SQL Fiddle.请注意,由于行是随机选择的,因此每次执行都可以获得不同的路径。