如何在同一个表中应用查询?

时间:2017-12-22 22:47:10

标签: sql sql-server

我有一个非常简单的问题,但我似乎无法找到答案。

我有下表:

declare @Register table (Citizen  nvarchar(50), Role    nvarchar(10), Process nvarchar(10))

insert @Register values 
      ( 'A', 'seller'  , 'Process1' )
    , ( 'A', 'seller'  , 'Process1' )
    , ( 'A', 'seller'  , 'Process1' )
    , ( 'A', 'seller'  , 'Process2' )
    , ( 'A', 'buyer'   , 'Process3' )
    , ( 'A', 'seller'  , 'Process3' )
    , ( 'B', 'seller'  , 'Process3' )
    , ( 'B', 'seller'  , 'Process4' )
    , ( 'C', 'seller'  , 'Process4' )

我想知道如何提取作为卖方在多个流程中进行交互的公民以及作为卖方的不同流程的数量。我还想在输出表中添加ProcessNumber(例如,如果一个公民在3个不同的流程中是卖家,它将为每个流程生成一行,在这种情况下,3。显示该人员作为卖方参与的流程)和这个公民卖家的不同程序的数量(在这个引用的例子中,它是3,因为公民在3个不同的过程中是卖家)

结果将是:

    Citizen   | Process  | Number_Of_Diff_Process_as_Seller
   -----------+----------+------------------------------------
    A         | Process1 |   3
    A         | Process2 |   3
    A         | Process3 |   3
    B         | Process3 |   2
    B         | Process4 |   2

3 个答案:

答案 0 :(得分:1)

SELECT DISTINCT a.Citizen, a.Process, b.Number_Of_Diff_Process_as_Seller
FROM @Register a
INNER JOIN (SELECT Citizen, COUNT(DISTINCT Process) Number_Of_Diff_Process_as_Seller FROM @Register WHERE Role = 'seller' GROUP BY Citizen) b
ON a.Citizen = b.Citizen
WHERE a.Role = 'seller' AND b.Number_Of_Diff_Process_as_Seller> 1

无法弄清楚为什么每个公民都需要每个公民的流程数量,但我认为这超出了范围。

答案 1 :(得分:1)

select t.Citizen,Process,Number_Of_Diff_Process_as_Seller
  from t
  join (select Citizen, count(distinct Process) as Number_Of_Diff_Process_as_Seller
          from t
          where Role = 'seller'
          group by Citizen) c
    on t.Citizen = c.Citizen
  group by t.Citizen, Process
  having Number_Of_Diff_Process_as_Seller > 1;

答案 2 :(得分:0)

这里不需要JOIN。直接的分析功能可以找到你需要的东西......

SELECT
    *
FROM
(
    SELECT
        citizen,
        process,
        COUNT(*) OVER (PARTITION BY citizen)   AS unique_seller_process_count
    FROM
        register
    WHERE
        role = 'seller'
    GROUP BY
       citizen,
       process
)
    filtered_summary
WHERE
    unique_seller_process_count > 1

http://sqlfiddle.com/#!6/53de2/2

如果您拥有的数据越多,没有联接的好处就越明显,因为您只扫描一次(而不是两次)并且不需要重新搜索行数据已经解析过,并且不需要为DISTINCT关键字应用昂贵的排序。

这与适当的索引组合的(在上述链接的sqlfiddle示出)意味着分析功能的方法很可能是可以得到的数据集的任何尺寸的最快的。

  • SQLFiddle还允许您查看执行计划
  • 两个计划都有INDEX SCAN
  • 两个计划都有NESTED LOOP (INNER JOIN)
  • 此解决方案避免了INDEX SEEK (已将总费用减半)
  • 此解决方案避免了DISTINCT SORT (优于再次将费用减半)

总体成本结果是,此答案的总成本为INDEX SCAN的105.3%,其中替代成本超过索引扫描的550%。