我很难搞清楚SQL查询。 我想选择所有只有名称包含“Test”的许可证的公司。
Company License
|pkId|Name | |pkId|CompanyId|Name |
----------------- -----------------------------
|1 |Microsoft | |1 |1 |License Test|
|2 |Apple | |2 |1 |Commercial |
|3 |2 |License Test|
|4 |2 |License Test|
因此,在示例中,Microsoft有2个许可证。一次测试和一次商业广告 所以我不想要那家公司。 但所有Apples许可证都是测试许可证,所以我想选择Apple。
我在想的是:
SELECT Company.Name, COUNT(Company.Name)
FROM Company INNER JOIN License ON License.CompanyId = Company.pkId
WHERE License.Name LIKE '%Test%'
GROUP BY Company.Name
获取每个公司包含“Test”的行数,并将其与
进行比较SELECT Company.Name, COUNT(Company.Name)
FROM Company INNER JOIN License ON License.CompanyId = Company.pkId
GROUP BY Company.Name
如果计数没有差异,我的公司只有测试许可证。 但我不知道如何将它们放在一起或者是否有更好的方法。
答案 0 :(得分:0)
你想要的是从另一个集合中减去一个集合(也就是说,返回一个集合,但没有出现在另一个集合中的行),这就是EXCEPT(或Oracle中的MINUS)运算符所做的事情。此查询应该为您提供所需内容:
SELECT c.pkId, c.Name FROM Company c
INNER JOIN License l ON c.pkId=l.CompanyId
WHERE l.Name LIKE '%Test%'
EXCEPT
SELECT c.pkId, c.Name FROM Company c
INNER JOIN License l ON c.pkId=l.CompanyId
WHERE l.Name NOT LIKE '%Test%'
还有其他方法,但这应该是最直接的。
答案 1 :(得分:0)
如果它是SQL Server数据库,则尝试此操作: -
declare @company table (pkid int, name varchar(20))
insert into @company values (1,'microsoft')
insert into @company values (2,'apple')
declare @license table (pkid int, companyid int, name varchar(20))
insert into @license values (1,1,'license test')
insert into @license values (2,1,'comm')
insert into @license values (3,2,'license test')
insert into @license values (4,2,'license test')
select * from @company
select * from @license
select c.name
from @license l
inner join @company c
on c.pkid = l.companyid
where l.companyid not in
(select companyid from @license l1
where l1.name not like '%test%')
group by c.name
答案 2 :(得分:0)
如果所有公司都拥有至少一个许可证,则以下内容将起作用。它检查是否有任何非“测试”的许可证:
SELECT c.Name
FROM Company c LEFT JOIN
License l
ON l.CompanyId = c.pkId AND l.Name NOT LIKE '%Test%'
WHERE l.CompanyId IS NULL
GROUP BY c.Name;
我认为,我更喜欢使用exists
和not exists
条款执行此操作:
select c.*
from company c
where exists (select 1
from License l
where l.CompanyId = c.pkId and l.Name LIKE '%Test%'
) and
not exists (select 1
from License l
where l.CompanyId = c.pkId and l.Name not LIKE '%Test%'
);
这表示至少有一行“test”存在,没有没有。
或者,您可以将其标记为聚合查询中的having
子句:
select c.Name
from Company c inner join
License l
ON l.CompanyId = c.pkId
group by c.Name
having sum(case when l.Name like '%Test%' then 1 else 0 end) > 0 and
sum(case when l.Name not like '%Test%' then 1 else 0 end) = 0;
答案 3 :(得分:0)
我已经复制了你的例子,第一个查询的结果是(2,1),第二个查询的结果是(2,2)。
SELECT COUNT(License.Name) AS counter, Company.Name
FROM Company INNER JOIN License ON License.CompanyId = Company.pkId
WHERE License.Name LIKE '%Test%'
GROUP BY Company.Name
HAVING counter = (SELECT MAX(counted) FROM (SELECT COUNT(l.Name) AS counted FROM License AS l WHERE l.name LIKE '%Test%' GROUP BY l.companyid) AS co)