Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 仅当“相关实体”列包含特定值时才选择_Sql_Database_Select_Sql Server 2008 R2 - Fatal编程技术网

Sql 仅当“相关实体”列包含特定值时才选择

Sql 仅当“相关实体”列包含特定值时才选择,sql,database,select,sql-server-2008-r2,Sql,Database,Select,Sql Server 2008 R2,我很难理解sql查询。 我想选择所有只拥有名称包含“Test”的许可证的公司 因此,在示例中,Microsoft有2个许可证。一次测试和一次商业测试 所以我不想要那家公司。 但是所有苹果的许可证都是测试许可证,所以我想选择苹果 我想的是: SELECT Company.Name, COUNT(Company.Name) FROM Company INNER JOIN License ON License.CompanyId = Company.pkId WHERE License.Name

我很难理解sql查询。 我想选择所有只拥有名称包含“Test”的许可证的公司

因此,在示例中,Microsoft有2个许可证。一次测试和一次商业测试 所以我不想要那家公司。 但是所有苹果的许可证都是测试许可证,所以我想选择苹果

我想的是:

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
如果数量上没有差异,我有一家公司只有测试许可证。
但是我不知道如何将它们全部合并,或者是否有更好的方法。

您想要的是从另一个集合中减去一个集合(即返回一个集合,但不在另一个集合中显示行),这就是(在Oracle中为负)操作符所做的。此查询应提供您想要的内容:

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%'
还有其他方法可以做到这一点,但这应该是最直接的方法


.

如果是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

如果所有公司都至少有一个许可证,则以下操作将起作用。它检查是否有不用于“测试”的许可证:

但是,我认为我更喜欢使用
exists
notexists
子句:

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;

我复制了您的示例,第一个查询的结果是(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)

当询问数据库相关问题时,您应该始终指定您正在使用的特定数据库系统;能力和解决方案各不相同。你说得对。现在编辑,谢谢!按照我希望的方式工作。第一个查询似乎返回相反的结果(它得到了Microsoft,但没有苹果的示例数据)。@jpw。真奇怪。不知怎么的,我只是没有完成那个查询。现在是
where
左连接,因此应该可以工作。
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;
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)