简体   繁体   English

SQL 如何根据条件进行内连接

[英]SQL how to inner join based on a condition

I have two tables - one called customers consisting of the fields id, name and referrals and another table called devices consisting of the fields id and type - where type is either 'mobile' or 'laptop'.我有两个表 - 一个称为客户,由字段 id、名称和推荐组成,另一个表称为设备,由字段 id 和类型组成 - 其中类型是“移动”或“笔记本电脑”。 The id field in the devices table corresponds to the id of a customer in the customers table. devices 表中的 id 字段对应于 customers 表中客户的 id。 Note one customer can have 2 entries in the devices table if they have used both a mobile and a laptop.请注意,如果一位客户同时使用了移动设备和笔记本电脑,则他们可以在设备表中拥有 2 个条目。

I'm trying to query something which returns a persons 'name', the devices they have used (lets call this 'devices_used') and 'referrals' where 'name' and 'referrals' come from the customers table and 'devices_used' is as follows: when a customer ONLY has a mobile entry in the devices table then this field should be populated as 'mobile', when ONLY laptop then this should be 'laptop' but if a client has both a mobile and laptop entry in the devices table then this should be populated as 'both'.我正在尝试查询返回人员“姓名”、他们使用的设备(我们称之为“devices_used”)和“推荐人”,其中“姓名”和“推荐人”来自客户表,“devices_used”是如下:当客户在设备表中只有移动条目时,此字段应填充为“移动”,当只有笔记本电脑时,应为“笔记本电脑”,但如果客户在设备中同时具有移动和笔记本条目那么这应该填充为“两者”。

I'm not really sure how to do this as something like我不太确定如何做到这一点

select c.name, d.type, c.referrals 
from customers c 
inner join devices d on c.id = d.id

isn't what I'm looking for since this would return two rows for the same customer if they have used both a mobile and a laptop - I'm looking for a query which which return just one row per customer and in the case they have used both devices the 'devices_used' field should be populated as 'both'.不是我要找的,因为如果他们同时使用移动设备和笔记本电脑,这将为同一客户返回两行 - 我正在寻找一个查询,它只返回每个客户一行,如果他们已使用这两种设备,“devices_used”字段应填充为“both”。

Making some assumptions, I believe you could simply use a GROUP BY to deduplicate what you are looking for.做出一些假设,我相信您可以简单地使用 GROUP BY 来删除您要查找的内容。

select c.name, d.type, c.referrals 
from customers c 
inner join devices d on c.id = d.id
group by c.name, d.type, c.referrals

Alternatives might include looking at your channel (device used) one at a time and using a UNION to put them back together, but it depends on your goal.替代方案可能包括一次查看一个频道(使用的设备)并使用 UNION 将它们重新组合在一起,但这取决于您的目标。

WITH device_numbers AS (
     SELECT c.id,
           COUNT(d.type) AS num_devices
     FROM customers c
     JOIN devices d
     ON c.id = d.id
     GROUP BY 1
)

SELECT c.name, 
     CASE WHEN num_devices = 2 THEN 'both'
     ELSE d.type END AS devices_used
FROM customers c
JOIN devices d
ON c.id = d.id
JOIN device_numbers dn
ON c.id = dn.id

I'm assuming you need to aggregate your devices table, you can easily do this by applying it for each customer.我假设您需要聚合您的设备表,您可以通过为每个客户应用它来轻松地做到这一点。

The following makes some guesses you may need to amend as appropriate, eg catering for NULL values以下是您可能需要适当修改的一些猜测,例如满足 NULL 值

select c.name, d.[type], c.referrals 
from customers c 
outer apply (
  select case when Count(*)=1 then Max([type]) else 'both' end
    from devices d
    where d.id = c.id
    group by d.id
)d([type]);

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

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