在SQL中没有聚合函数对数据进行分组

时间:2015-02-04 20:13:48

标签: sql sql-server-2012

我想知道是否有人可以对此问题提供一些见解。我正在管理一些必须包含相同股票的股票投资组合。我需要设计一个查询,将所有投资组合与所有投资组合进行比较,并返回存在于一个中的股票,而不是另一个。

为简单起见,假设我有一张如下表:

stock_symbol     portfolio
AAPL                A
IBM                 A
MCD                 A
NFLX                A
AAPL                B
IBM                 B
MCD                 B
FB                  B
AAPL                C
IBM                 C
MCD                 C

理想情况下,我希望查询返回类似这样的内容:

p1    p2    stock_symbol
A     B         NFLX
A     C         NFLX
B     A          FB
B     C          FB

因此,比较A和B将返回NFLX,而将B与A进行比较将返回FB。

目前,我有一个适用于少量投资组合的查询,但我很快将会管理> 20个投资组合。这是数以百计的比较。我想使用GROUP BY,但我没有聚合函数。

关于我能做什么的任何想法?谢谢!

2 个答案:

答案 0 :(得分:3)

此类查询不需要group by。它需要left join。这是一个应该执行您想要的示例查询:

select p1.portfolio, p2.portfolio, p1.stock_symbol
from table p1 left join
     table p2
     on p1.stock_symbol = p2.stock_symbol and
        p1.portfolio <> p2.portfolio
where p2.stock_symbol is null;

编辑:

p2.portfolio将是NULL,这是一个很好的观点。这是一个更好的解决方案:

select p1.portfolio, p2.portfolio, p1.stock_symbol
from (select distinct portfolio from table)  p1 cross join
     (select distinct portfolio from table) p2 left join
     table sp1 
     on sp1.portfolio = p1.portfolio left join
     table sp2
     on sp1.stock_symbol = sp2.stock_symbol 
where sp2.stock_symbol is null;

答案 1 :(得分:0)

试一试......

设定:

select * into #tbla from (
SELECT 'AAPL' stock_symbol, 'A' portfolio union all
SELECT 'IBM ',              'A' union all
SELECT 'MCD ',              'A'union all
SELECT 'NFLX',              'A'union all
SELECT 'AAPL',              'B'union all
SELECT 'IBM ',              'B'union all
SELECT 'MCD ',              'B'union all
SELECT 'FB  ',              'B'union all
SELECT 'AAPL',              'C'union all
SELECT 'IBM ',              'C'union all
SELECT 'MCD ',              'C'
)a

查询:

    WITH symbols
AS (
    SELECT DISTINCT stock_symbol
    FROM #tbla
    )
    ,portfolios
AS (
    SELECT DISTINCT portfolio
    FROM #tbla
    )
    ,mstr
AS (
    SELECT *
    FROM portfolios A
    CROSS JOIN symbols B
    )
    ,interim
AS (
    SELECT *
    FROM mstr m
    WHERE NOT EXISTS (
            SELECT 1
            FROM #tbla A
            WHERE m.portfolio = A.portfolio
                AND m.stock_symbol = A.stock_symbol
            )
    )
SELECT A.portfolio
    ,b.portfolio
    ,b.stock_symbol
FROM interim A
CROSS JOIN interim B
WHERE A.portfolio <> B.portfolio
    AND A.stock_symbol <> B.stock_symbol

结果:

portfolio   portfolio   stock_symbol
A           B             NFLX
A           C             NFLX
B           A             FB  
B           C             FB  
C           B             NFLX
C           A             FB