【问题标题】:Best SQL query to retrieve the data which has all required data检索具有所有必需数据的数据的最佳 SQL 查询
【发布时间】:2018-01-16 13:22:52
【问题描述】:

我有一个交易表,其中包含每个公司的项目详细信息。我想编写一个查询来检索只有项目编号 1,2 和 3 的公司(根据下面的示例代码)。选定的公司应具有所有 1,2,3 项。如果某些公司只有第 1 项,那么它不应该出现。这个怎么写?

CREATE TABLE #TmpTran 
(
     ID BIGINT IDENTITY, 
     COMPANY_ID BIGINT, 
     ITEM_NAME VARCHAR(50), 
     ITEM_NUMBER INT
)

INSERT INTO #TmpTran (COMPANY_ID, ITEM_NAME, ITEM_NUMBER)
VALUES (1, 'ABC', 1), (1, 'DEF', 2), (1, 'HIJ', 3),
       (2, 'KLM', 4), (2, 'KLM', 5), (2, 'ABC', 1)

如何使用 WHEREJOIN 查询仅获取公司 1 数据?

【问题讨论】:

  • 当有一家公司有 1,2,3 和 4 项编号时会发生什么,该公司会成为结果的一部分吗?
  • 是的...因为该公司拥有我们搜索的所有项目(本例中为 1,2,3)。我想加载所有拥有所有搜索项的公司。
  • 那我更喜欢戈登的回答..

标签: sql sql-server


【解决方案1】:

您可以使用group byhaving 做到这一点:

select company_id
from #tmptran tt
where item_number in (1, 2, 3)
group by company_id
having count(distinct item_number) = 3;

【讨论】:

  • 你能解释一下“count(distinct item_number) = 3;”这里?为什么 3 是硬编码的。
  • @user2837480 :在此查询中,您首先获取所有 item_number 为 1、2 或 3,然后是 @987654325 @company_id 将所有这些行放在一起。在您的样本数据中,company_id = 1 将有 3 个这样的匹配行,而 company_id = 2 将只有 1 个这样的匹配行。 HAVING COUNT(DISTINCT item_number) 就像在 GROUP BY 之后应用的第二个 WHERE。这个计算每个 company_id 有多少不同的 item_number(distinct 用于公司多次使用相同的 item_number)。 3 是硬编码的,因为您要搜索 3 个不同的 item_numbers。
  • @user2837480 。 . . count(distinct) 确保每个公司的所有三个值都存在。 “3”是您要查找的值的数量。
【解决方案2】:

另一种方式(更灵活的方式)

select company_id
from #tmptran tt
group by company_id
having count(case when item_number = 1 then 1 end) > 0;
   and count(case when item_number = 2 then 1 end) > 0;
   and count(case when item_number = 3 then 1 end) > 0;

【讨论】:

  • 需要全表扫描,但这并不总是必要的。有时全表扫描无论如何都会发生,但@GordonLinoff 的回答至少有可能不会发生。
  • 不应该是:count(item_number = 1 then 1 end) > 0 and...
  • 实际上我在临时表中发送所需的项目编号。我担心我会返回大约 20 列数据。所以把它们都放在一个组中会很乱。你有其他解决方案吗?感谢您的帮助!
  • @user2837480 - 请用一个具体的例子更新你的问题?包括输入数据和预期结果?
【解决方案3】:
select tt.company_id
from #tmptran tt
where tt.item_number in (1, 2, 3)
group by tt.company_id
having sum(max(case tt.item_number when 1 then 1 end)) +
   and sum(max(case tt.item_number when 2 then 1 end)) +
   and sum(max(case tt.item_number when 3 then 1 end)) = 3

【讨论】:

  • 目前HAVING子句的作用与WHERE子句一样,还有一些额外的必要工作。这使得WHERE 子句变得多余,或者HAVING 子句过于复杂。我建议删除WHERE 子句或将HAVING 子句更改为COUNT(DISTINCT item_number) = 3
【解决方案4】:

你说你有很多领域。读者最容易理解的可能是这样的:

select distinct tt.company_id
from #tmptran tt
where tt.item_number in (1, 2, 3)
and exists(select 1 
           from #tmptran ttSub 
           where ttSub.company_id = tt.company_id and ttSub.item_number = 1)
and exists(select 1 
           from #tmptran ttSub 
           where ttSub.company_id = tt.company_id and ttSub.item_number = 2)
and exists(select 1 
           from #tmptran ttSub 
           where ttSub.company_id = tt.company_id and ttSub.item_number = 3)

【讨论】:

    猜你喜欢
    • 2012-04-27
    • 1970-01-01
    • 1970-01-01
    • 2018-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-27
    • 1970-01-01
    相关资源
    最近更新 更多