【问题标题】:MS SQL - Select data from many-to-many table in which a column's values matches all given valuesMS SQL - 从多对多表中选择数据,其中列的值与所有给定值匹配
【发布时间】:2019-02-11 05:42:23
【问题描述】:

我有一个名为 SUPPLIER_CATEGORY 的表作为 SUPPLIER 和 CATEGORY 表之间的多对多关系。我想要的是从 SUPPLIER_CATEGORY 表中获取与给定的所有 CATEGORY_ID 匹配的 SUPPLIER_ID。

例如,考虑下表

SUPPLIER_ID    CATEGORY_ID

101                1
101                2
102                1
102                3
103                1
103                2
103                3

如果我想获取 CATEGORY_ID 1 和 2 的 SUPPLIER_ID。查询应返回 SUPPLIER_ID 101 和 103 但不是 102,但它的 CATEGORY_ID = 1。因为它不包含 CATEGORY_ID 2。希望它有意义。

编辑:

注意: CATEGORY_ID 可以是 2 个以上的数字。

谢谢。

【问题讨论】:

  • 以表格形式提供样本数据和您的预期输出
  • @codeworks 试过了。但即使找到单个 CATEGORY_ID 也会返回记录。该表有 14 条 CATEGORY_ID 为 1 的记录和 12 条 CATEGORY_ID 为 2 的记录。当我使用 IN 时,它返回 14 条记录,它应该返回更少
  • @fa06 提供的表是样本数据,输出只是 SUPPLIER_ID

标签: sql sql-server


【解决方案1】:

对于给定的示例数据,下面将是查询。

select supplier_id
from <tableName>
where category_id in (1, 2)
group by supplier_id
having count(*) > 1

【讨论】:

  • 在什么基础上您需要给定输入的供应商 id,或者说表中不同的 category_id 是 1,2,3...5,您需要具有所有类别 id 还是仅具有选择类别的供应商身份证
  • 我想要作为参数传递的类别 ID 的供应商 ID
  • 上述查询仍然有效,您必须参数化供应商 ID 和供应商 ID 计数...您必须再传递一个带有供应商 ID 计数的参数。
  • 此解决方案完美运行。我只需要了解 HAVING 子句。感谢您快速轻松地回复。
【解决方案2】:

你可以试试下面-

select SUPPLIER_ID from tablename where CATEGORY_ID in (1,2)
group by SUPPLIER_ID  having count(distinct CATEGORY_ID)=2

【讨论】:

    【解决方案3】:
    DECLARE @catIds varchar(max)='1,2'
    DECLARE @SplitOn CHAR = ','
    
    -------------- spliting all CATEGORY_ID ---- 
    DECLARE @RtnTable TABLE (catId int )
    DECLARE @Count int
    SET @Count = 1
    WHILE (CHARINDEX(@SplitOn,@catIds)>0)
    
    BEGIN
        INSERT INTO @RtnTable (catId)
    
    SELECT
        Value = LTRIM(RTRIM(SUBSTRING(@catIds,1,CHARINDEX(@SplitOn,@catIds)-1)))
    
        SET @catIds = SUBSTRING(@catIds,CHARINDEX(@SplitOn,@catIds)+LEN(@SplitOn),LEN(@catIds))
    Set @Count = @Count + 1
    END
    
    INSERT INTO @RtnTable (catId)
    
    SELECT
        Value = LTRIM(RTRIM(@catIds))
    
    -------------------------------------------------
    
    
    --------------- main part ---------------
    SELECT  [SUPPLIER_ID]      
      FROM [EmployeeDb].[dbo].[SUPPLIER_CATEGORY]
      WHERE CATEGORY_ID in(SELECT * from @RtnTable)
      GROUP BY [SUPPLIER_ID]
      HAVING (count(CATEGORY_ID)=  @Count )
    
    --------------- main part ---------------
    

    【讨论】:

    • 您的解决方案完美运行。我只需要将 category_ids 连接到@catIds。这适用于任意数量的 category_id。谢谢你。
    【解决方案4】:

    您可以将此程序化解决方案用作您的用户输入。

    DECLARE @ids NVARCHAR(MAX) = N'1,2'
    DECLARE @input_xml XML = Cast('<root><x>'+ Replace(@ids, ',', '</x><x>')+ '</x></root>' AS XML) 
    
    DECLARE @list_to_table TABLE(Id BIGINT)
    
    INSERT INTO @list_to_table
    SELECT DISTINCT f.x.value('.', 'BIGINT') AS Id
    FROM @input_xml.nodes('/root/x') f(x);
    
    SELECT sc.supplier_id      
    FROM supplier_category sc
    INNER JOIN @list_to_table ltt on sc.category_id = ltt.id
    GROUP BY sc.supplier_id 
    HAVING count(DISTINCT sc.category_id ) = (SELECT COUNT(1) FROM @list_to_table);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-12
      • 2020-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多