简体   繁体   English

SQL查询返回另一个表中不匹配的行

[英]SQL Query to return rows with no matches in another table

I have a users country table where I hold a list of users country's- a user can have many addresses and therefore many country's 我有一个用户国家/地区表,其中保存着一个国家/地区的用户列表-一个用户可以有许多地址,因此有许多国家/地区的地址

it is joined to the user table via an address table 它通过地址表连接到用户表

if I do a select distinct CountryId from UserCountry Data returned is: 如果我从UserCountry中选择不同的CountryId,则返回的数据是:

1
2
3
4
5
6
etc

If I run the following query I get a User returned 如果我运行以下查询,我得到一个返回的用户

select * from User u join Address a
on u.AddressId = a.Id
where a.CountryId = 1

If I then run 如果我再跑

select * from User u join Address a
on u.AddressId = a.Id
where a.CountryId = 2

I get no data returned which is fine. 我没有返回任何数据,这很好。 What I need to to do is pass in a list of all the distinct Country Ids and produce a output of which set return a User Object and which set don't return a User object 我需要做的是传递所有不同国家(地区)ID的列表,并生成输出的结果返回一个用户对象,而哪个不返回用户对象

The following query: 以下查询:

SELECT CountryId, COALESCE(t2.cnt, 0) AS usersPerCountry 
FROM (
   SELECT DISTINCT CountryId 
   FROM UserCountry) AS t1
LEFT JOIN (
   SELECT a.CountryId, COUNT(*) AS cnt
   FROM User u 
   INNER JOIN Address a ON u.AddressId = a.Id
   GROUP BY a.CountryId
) AS t2 ON t1.CountryId = t2.CountryId
ORDER BY COALESCE(t2.cnt, 0) DESC

will give you the number of users associated with each country. 将为您提供与每个国家/地区关联的用户数。 If a country is not related to any users at all then 0 is returned. 如果一个国家根本不与任何用户相关,则返回0

Explanation: 说明:

The above query makes use of two derived tables, t1 and t2 : 上面的查询使用了两个派生表t1t2

  • The first derived table of the query, t1 , contains a list of all distinct CountryId values contained in UserCountry . 查询的第一个派生表t1包含UserCountry包含的所有不同CountryId值的列表。
  • The second derived table, t2 , returns the number of users per CountryId . 第二个派生表t2返回每个CountryId的用户数。 Ids with no users are not returned by this sub-query. 没有子用户的ID不会由此子查询返回。

Performing a LEFT JOIN between t1 and t2 with t1 as the first table returns all values of t1 , ie all CountryId values contained in UserCountry . 使用t1作为第一个表在t1t2之间执行LEFT JOIN ,返回t1 所有值,即UserCountry包含的所有 CountryId值。 If there is no match in t2 , then t2.cnt is NULL . 如果t2没有匹配项,则t2.cntNULL COALESCE used in the SELECT clause converts this NULL value into a 0 . SELECT子句中使用的COALESCE将此NULL值转换为0

This will give you all items in User and Address that do not have a Country entry. 这将为您提供用户和地址中没有国家条目的所有项目。 Is this what you are looking for? 这是你想要的?

SELECT *
FROM User U
JOIN Address a
ON a.Id = u.AddressId
WHERE NOT EXISTS
(
   SELECT 1
   FROM UserCountry uc
   WHERE uc.CountryId = a.CountryId
);

For the list of Country items that do not have a User, you can alternate the statements and find where the CountryId NOT EXISTS in the User and Address tables 对于没有用户的Country项目列表,您可以替换语句,并在“ User和“ Address表中查找“ CountryId NOT EXISTS存在”的位置

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM