2

编辑:我意识到我问错了问题。我真正想问的是,“给定一组值[Column B],检查其中是否有一个值[Column A]与所有集合匹配,而没有其他值。”


我不确定我想做的事情是否有正式名称,所以很难找到我的问题。

给定一个有 2 列和一个值列表的表,我想看看这个组合(并且只有这个组合)是否存在于表中。

例如,给定这个表(假设它是整个表):

|----------|----------|
| Column A | Column B |
|----------|----------|
| 12345    | abcde    |
|----------|----------|
| 12345    | xyz      |
|----------|----------|
| 12345    | abcd     |
|----------|----------|
| 12345    | abbba    |
|----------|----------|

并给出这个输入参数:

Declare @columnBs Varchar(Max) = '["abcde","xyz","abcd","abbba"]';

对于那套,我想退货12345。所以,基本上,我想运行一个检查,看看是否有任何值[Column A]与所有值相匹配[Column B]@columnBs 并且没有其他值

如果没有[Column A]作为起点的价值,我什至无法构思一个长形式的解决方案。


如果它有助于更​​好地概念化这一点,这是一个消息传递解决方案,其中:

  • [Column A]表示线程的主键
  • [Column B]表示分配给线程的用户

因此,如果一组用户收到一条新消息,我想查看是否存在由所有用户提供的现有线程,@columnBs而没有其他用户。

4

2 回答 2

1

我读到这篇文章,您需要在 ColumnA 中找到一个值,该值与查询中的相同值完全对应,不多也不少。因此,您需要加入搜索值,确保单个 ColumnA 的所有值都存在,然后确保不再存在。您可以通过交叉连接它们来做到这一点,但是对于更大的数据集,这将具有糟糕的性能。这可能会好一点:

-- Set up the source data.
create table MyTable (
        ColumnA int,
        ColumnB nvarchar(max)
    )
insert MyTable
    (ColumnA, ColumnB)
    Values
    -- Value 1 contains exactly the same values as we'll be looking for
    (1, 'abcde'),
    (1, 'xyz'),
    (1, 'abcd'),
    (1, 'abbba'),
    -- Value 2 contains all of them, plus one more different value
    (2, 'abcde'),
    (2, 'xyz'),
    (2, 'abcd'),
    (2, 'abbba'),
    (2, 'xxxxx'),
    -- Value 3 contains one less value
    (3, 'abcde'),
    (3, 'xyz'),
    (3, 'abcd'),
    -- Value 4 contains one different value
    (4, 'abcde'),
    (4, 'xyz'),
    (4, 'abcd'),
    (4, 'xxxxxxxxx')


-- These are the values we are looking for:
create table #searchValues (
            value nvarchar(max)
        )
insert #searchValues
    (value) values
    ('abcde'),
    ('xyz'), 
    ('abcd'), 
    ('abbba')

declare @valueCount int = (select COUNT(*) from #searchValues)


select  t.ColumnA
    from (
        -- This inner query finds all ColumnA values
        -- that link to all of the specified ColumnB values.
        select  tab.ColumnA
            from #searchValues t
            join MyTable tab on
                t.value = tab.ColumnB
            group by tab.ColumnA
            having COUNT(*) = @valueCount
        ) x
    -- And this outer join and group by will filter out those that 
    -- have all the values, plus some more.
    join MyTable t on
        t.ColumnA = x.ColumnA
    group by t.ColumnA
    having COUNT(*) = @valueCount



drop table #searchValues
drop table MyTable

这将只产生值 1 作为结果,因为它完全匹配。

于 2017-11-30T00:55:22.517 回答
0

如果您使用的是 SQL Server 2016 及更高版本,请使用 STRING_SPLIT()。如果您使用 SQL Server 的早期版本,则可以使用此http://www.sqlservercentral.com/articles/Tally+Table/72993/ 将 CSV 解析为逐列结果列表

declare @table table
(
    ColumnA int,
    ColumnB varchar(6)
)

insert into @table select 12345, 'abcde'
insert into @table select 12345, 'xyz'
insert into @table select 12345, 'abcd'
insert into @table select 12345, 'abbba'

declare @columnBs varchar(max) = 'abcde,xyz,abcd,abbba';

; with cte as
(
    select  value, cnt = count(*) over()
    from    string_split(@columnBs, ',')
)
select  ColumnA
from    cte c
    inner join @table t on  c.value = t.ColumnB
group by ColumnA
having count(*) = max(c.cnt)
于 2017-11-30T00:48:12.010 回答