在同一SQL查询中匹配多个值

在同一SQL查询中匹配多个值,sql,sql-server,Sql,Sql Server,我有一张具有以下结构的桌子 Table Name: CustomerStocks Structure Name Varchar(25) StockSymbol Varchar(4) 以下是表格内容的示例 股票名称符号 目标是给客户一个名字,我如何找到拥有类似投资组合的其他客户的名单。换句话说,原始客户的所有权益都必须存在 因此,如果我在寻找拥有类似Jen投资组合的客户,那么结果将是Judy和Sam 如果我在搜索拥有类似Ju

我有一张具有以下结构的桌子

Table Name: CustomerStocks

Structure 
Name                     Varchar(25) 
StockSymbol              Varchar(4)
以下是表格内容的示例

股票名称符号

目标是给客户一个名字,我如何找到拥有类似投资组合的其他客户的名单。换句话说,原始客户的所有权益都必须存在

因此,如果我在寻找拥有类似Jen投资组合的客户,那么结果将是Judy和Sam

如果我在搜索拥有类似Judy投资组合的客户,那么结果将是Sam

然而,如果我用Brian的公文包搜索客户,它可以不返回行,也可以只返回Brian

这可能吗?如果是这样,如何编写sql查询来实现这一点

在此方面,我们真诚地感谢您的帮助。

这应该可以:

declare @Name varchar(25) = 'Judy'

select * from CustomerStocks cs
where cs.StockSymbol in 
    (select x.StockSymbol 
     from CustomerStocks x 
     where x.Name = @Name)
或者排除朱迪:

declare @Name varchar(25) = 'Judy'

select * from CustomerStocks cs
where cs.StockSymbol in 
    (select x.StockSymbol 
     from CustomerStocks x 
     where x.Name = @Name
     and x.Name <> cs.Name)
一个小的调整之后

我没有测试过这个,但有点像

DECLARE @name VARCHAR(24) = 'Judy';

WITH cte_stocks AS (
    SELECT StockSymbol
    FROM CustomerStocks
    WHERE Name = @name
)
SELECT Name
FROM CustomerStocks cs
LEFT JOIN cte_stocks a ON cs.StockSymbol = a.StockSymbol
GROUP BY cs.Name
HAVING COUNT(DISTINCT a.StockSymbol) = (SELECT COUNT(1) FROM cte_stocks)

…可能会这样做

好的,那么这个怎么样:

declare @Name Varchar(25) = 'Judy'
declare @table (StockSymbol varchar(4))

--Get StockSymbols to search for
insert into @table
select cs.StockSymbol 
from CustomerStocks cs 
where cs.Name = @Name
group by cs.StockSymbol


--Match against the people
select cs.Name from CustomerStocks cs
where (select count(*) 
     from CustomerStocks x 
     inner join @table t on x.StockSymbol = t.StockSymbol
     where x.Name = cs.Name
     group by x.StockSymbol) = (select count(*) from @table t)
group by cs.Name

类似的功能可能会工作,与引擎无关:

SELECT target.Name, 'similar_to', others.Name
FROM (
  SELECT Name, COUNT(*) numStocks
  FROM CustomerStocks
  GROUP BY Name
) target
  INNER JOIN (
    SELECT cs1.Name match, cs2.Name otherName, count(*) commonStocks
    FROM CustomerStocks cs1
      INNER JOIN CustomerStocks cs2
        ON cs1.StockSymbol = cs2.StockSymbol
          AND cs1.Name <> cs2.Name
    GROUP BY cs1.Name, cs2.Name
  ) others ON target.Name = others.match
      AND others.commonStocks >= numStocks.numStocks
带有和运算符的选项

DECLARE @Name Varchar(25) = 'Judy'       
SELECT *
FROM dbo.CustomerStocks s
WHERE NOT EXISTS (
                  SELECT s3.StockSymbol
                  FROM dbo.CustomerStocks s3
                  WHERE s3.Name = @Name
                  EXCEPT
                  SELECT s2.StockSymbol
                  FROM dbo.CustomerStocks s2
                  WHERE s2.Name = s.Name                        
                  ) AND s.Name != @Name
为了提高性能,请使用此索引

CREATE INDEX ix_StockSymbol_CustomerStocks ON CustomerStocks(StockSymbol) INCLUDE(Name)

演示

规则是Judy持有的整套股票必须与其他客户匹配,而不是一个客户。因此,如果Judy拥有AAPL、AMZN和GOOG,那么生成的行应该只是拥有这三种股票的客户列表,而不是其中的一种。这不会像询问者所希望的那样起作用。IN子句将匹配任何相关值,但不一定匹配所有值。感谢Robert的努力。但是,这并没有帮助。碰巧是哪个版本的Sql Server-2008或更高版本?SGEDES-使用Sql Server 2008 R2。作者可能希望包括所有其集合至少与相同的。如果是的话。。。这样至少所有的股票都是一样的。相似但必须包含所有在我心目中并不意味着完全相同。。但是,让我们一起行动吧decide@xQbert-不确定这会有什么不同;我试图想出一个例子来说明在本例中,=和>=之间的区别。在OP的有限设置中,>=和=返回相同的值。你能提供一个例子吗?客户有库存A、B、C用户2有库存A、B、C、D这不是书面的排除用户2吗?@xQbert-这与Sam和Judy的情况不一样吗?Judy Customer/@name有A、B、AAPL、AMZN;Sam用户2具有A、B、C AAPL、AMZN、GOOG;根据select语句,Sam和Judy在=和>=jimbobmcgee的结果中出现,COUNTDISTINCT a.StockSymbol=从cte_stocks中选择COUNT1。你能解释一下这个查询是如何工作的吗?
CREATE INDEX ix_StockSymbol_CustomerStocks ON CustomerStocks(StockSymbol) INCLUDE(Name)