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

问题描述 投票:-1回答:3

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

我有下表:

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
sql sql-server
3个回答
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
投票
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;

0
投票

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

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中显示)意味着Analytical Function方法可能是您获得任何大小的数据集的最快速度。

  • SQLFiddle还允许您查看执行计划
  • 这两个计划都有一个INDEX SCAN
  • 这两个计划都有一个NESTED LOOP (INNER JOIN)
  • 这个解决方案避免了INDEX SEEK(已经将整体成本减半)
  • 这个解决方案避免了DISTINCT SORT(比再次减少成本更好)

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

© www.soinside.com 2019 - 2024. All rights reserved.