【问题标题】:Get records having both values in "IN" using SQL使用 SQL 获取在“IN”中具有两个值的记录
【发布时间】:2012-04-23 18:00:42
【问题描述】:

我需要一条 SQL 语句来从数据库中提取具有两个附件标签的申请人。如果我想要一个具有 7 或 8 作为附件标签的申请人,但我需要同时具有这两个标签的申请人,那么下面的 q 语句可以正常工作。

select distinct(a.id) from applicant a
join applicantdeployment ad on a.id = ad.applicantid
join ApplicantAttachment at on a.id = at.applicantid
where a.applicanttype = 'TCN/LN' and ad.groundlocation in (4,8,14) and ad.deploymentstatus =1
and ad.trainingdeploymentstatus = 6 and at.tag in (7,8)

例如,从下面的集合中,我只想显示 ids 7332,7451 和 7449。

ID      标签
7328 8
7328 8
7332 8
7332 7
7337 7
7449 8
7449 7
7451 8
7453 7
7451 7

谢谢!

【问题讨论】:

    标签: sql relational-division


    【解决方案1】:

    你需要在下面做,而不是区分:

    GROUP BY a.id HAVING COUNT(a.id) = 2  
    

    【讨论】:

    • 这行得通!谢谢,但我想知道如果其中一个 ID 有标签 7 本身的 2 条记录,那会被计算在内……对吗?例如 ID 7328 还有一个标签 8。这是我的数据库结构中的一种可能性。很抱歉没有早点指出这一点
    • @sarsha - 然后执行:HAVING COUNT(DISTINCT at.Tag) = 2
    • 我尝试为此添加一个计数,因为我想要一个满足此条件的 ID 计数,并且正如预期的那样,它给了我每个 ID 的记录计数。所以这不能那样工作
    【解决方案2】:

    您可以加入 ApplicationAttachment 表两次以确保两个标签都存在。这样您就可以避免使用 DISTINCT 和 GROUP BY。

    SELECT a.id
    FROM applicant a
    JOIN applicantdeployment ad ON a.id = ad.applicantid
    JOIN ApplicantAttachment at7 ON a.id = at7.applicantid AND at7.tag = 7
    JOIN ApplicantAttachment at8 ON a.id = at8.applicantid AND at8.tag = 8
    WHERE a.applicanttype = 'TCN/LN' 
    AND ad.groundlocation IN (4,8,14)
    AND ad.deploymentstatus = 1
    AND ad.trainingdeploymentstatus = 6
    

    【讨论】:

    • 我仍然需要不同的,因为我只想要 ID。并且没有不同,它会为同一 ID 提供多条记录。但是是的,我不需要分组。
    【解决方案3】:

    在您的示例数据中,不应该选择 7451 吗?您需要修改以下代码以适合您的查询,但请尝试以下操作:

    CREATE TABLE #Temp
    (
        ID INT,
        Tag INT
    )
    
    INSERT INTO #Temp
    (
        ID,
        Tag
    )
    SELECT 7328, 8 UNION
    SELECT 7332, 8  UNION
    SELECT 7332, 7  UNION
    SELECT 7337, 7  UNION
    SELECT 7449, 8  UNION
    SELECT 7449, 7  UNION
    SELECT 7451, 8  UNION
    SELECT 7453, 7  UNION
    SELECT 7451, 7
    
    select distinct(ad.id) from #Temp ad
    join #Temp at on ad.id = at.id
    AND ad.Tag != at.Tag
    where at.tag in (7,8)
    AND ad.Tag IN (7, 8)
    

    【讨论】:

      【解决方案4】:

      如果将 IN 列表项放入名为#Tags 的表中,这将起作用,并且如果标签数量发生变化,则无需重写查询。

      select distinct(#Temp.ID)
      from #Temp
      where not exists (
        select * from #Tags
        where not exists (
          select * from #Temp as TempCopy
          where TempCopy.Tag = #Tags.Tag
          and TempCopy.ID = #Temp.ID
        )
      )  
      

      在英语中,这会选择那些没有缺少任何必需标签的 ID。

      【讨论】:

        【解决方案5】:

        试试:

        select distinct(a.id)
        from applicant a
        join applicantdeployment ad on a.id = ad.applicantid
        join (select applicantid from applicantattachment at1
        join applicantattachment at2 on at1.applicantid=at.applicantid
        where at1.tag=7 and at2.tag=8) at
        on a.id = at.applicantid
        where a.applicanttype = 'TCN/LN'
        and ad.groundlocation in (4,8,14)
        and ad.deploymentstatus =1
        and ad.trainingdeploymentstatus = 6
        

        将申请者附件表加入自身,只获取相关申请者ID。

        【讨论】:

        • 我应该补充一点,这不能很好地适应您希望标签全部超过两个值的情况。或者至少您需要为要检查的每个值加入一个连接。
        【解决方案6】:
        select distinct(a.id) from applicant a
        join applicantdeployment ad on a.id = ad.applicantid
        join ApplicantAttachment at on a.id = at.applicantid
        where a.applicanttype = 'TCN/LN' and ad.groundlocation in (4,8,14) and ad.deploymentstatus =1
        and ad.trainingdeploymentstatus = 6 and at.tag in (7,8) and a.id IN (7332,7449);
        

        【讨论】:

        • 我认为 OP 意味着找到一种无需对结果进行硬编码的方法 :)
        猜你喜欢
        • 2018-04-22
        • 2014-06-05
        • 2021-12-27
        • 2015-01-07
        • 1970-01-01
        • 1970-01-01
        • 2020-07-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多