我正在尝试在MS SQL Server中连接两个表 一个表包含人名和他们的ID。
+----+---------+--------------+---------+
| ID | Name | phone | email |
+----+---------+--------------+---------+
| 1 | John A. | 111-111-1111 | a@email |
| 2 | Sara B. | 111-111-1112 | b@email |
| 3 | Joe C. | 111-111-1113 | c@email |
| 4 | Jane D. | 111-111-1114 | d@email |
+----+---------+--------------+---------+
另一个表包含ID,他们知道的语言,以及指示它是否是他们的母语的位。
+----+----------+---------+
| ID | Language | Native |
+----+----------+---------+
| 1 | English | True |
| 1 | Spanish | False |
| 2 | Spanish | True |
| 2 | English | False |
| 2 | French | False |
| 3 | French | False |
| 3 | Spanish | False |
| 4 | English | True |
+----+----------+---------+
我想要的表格应该显示身份证,人名,母语或首先返回的语言,如果这是他们的母语,电话号码,电子邮件。
+----+---------+----------+--------+--------------+---------+
| ID | Name | Language | Native | phone | email |
+----+---------+----------+--------+--------------+---------+
| 1 | John A. | English | True | 111-111-1111 | a@email |
| 2 | Sara B. | Spanish | True | 111-111-1112 | b@email |
| 3 | Joe C. | French | False | 111-111-1113 | c@email |
| 4 | Jane D. | English | True | 111-111-1114 | d@email |
+----+---------+----------+--------+--------------+---------+
我尝试过加入表并提供where条件,但它只返回本地语言或该人知道的所有语言。我还尝试按ID分组,该ID表示所选列表中的列无效。我将所有列都放入group by子句中,但这给了我操作数数据类型位对于max运算符无效。
SELECT p.ID
,p.Name
,l.Language
,coalesce(max(l.native),0) as native
,p.phone
,p.email
FROM people as p
JOIN Languages as l on p.ID = l.ID
group by p.id
答案 0 :(得分:0)
SQL Server解决方案:
create table person (
id int,
name varchar (45),
phone varchar (45),
email varchar (45)
);
create table languages (
id int,
language varchar (45),
Native bit
);
insert into person values
(1, 'John A.', '111-111-1111', 'a@email'),
(2, 'Sara B.', '111-111-1112', 'b@email'),
(3, 'Joe C.', '111-111-1113', 'c@email'),
(4, 'Jane D.', '111-111-1114', 'd@email');
insert into languages values
(1, 'English', 1 ),
(1, 'Spanish', 0),
(2, 'Spanish', 1 ),
(2, 'English', 0),
(2, 'French', 0),
(3, 'French', 0),
(3, 'Spanish', 0),
(4, 'English', 1 );
select t1.id, t1.name, t2.language, t2.native, t1.phone, t1.email
from person t1 inner join
(select *, row_number () over (partition by id order by id) rn
from languages) t2 on t1.id = t2.id
where t2.rn =1
结果:
+----+---------+----------+--------+--------------+---------+
| id | name | language | native | phone | email |
+----+---------+----------+--------+--------------+---------+
| 1 | John A. | English | True | 111-111-1111 | a@email |
| 2 | Sara B. | Spanish | True | 111-111-1112 | b@email |
| 3 | Joe C. | French | False | 111-111-1113 | c@email |
| 4 | Jane D. | English | True | 111-111-1114 | d@email |
+----+---------+----------+--------+--------------+---------+
答案 1 :(得分:0)
如果你的RDBMS不支持窗口函数,那么这样的东西应该可以工作:
SELECT p.ID
,p.Name
,COALESCE(l.Language, l2.language) as language
,coalesce(l.native, l2.native) as native
,p.phone
,p.email
FROM people as p
LEFT OUTER JOIN Languages as l on p.ID = l.ID
AND (l.native = 'true')
LEFT OUTER JOIN (SELECT id, max(Language), native FROM Languages WHERE native = 'false' GROUP BY id, native) as l2 on p.ID = l2.ID
AND ()
group by p.id
答案 2 :(得分:0)
有几种方法可以做到这一点。你没有说你正在使用什么DBMS,所以我认为MySQL是最常见的开源产品。
您可以使用包含LIMIT 1子句的子查询(SQL Server中的TOP 1,但可能在子查询中不起作用)来执行此操作。
如果某人没有列出任何语言,您应该使用OUTER联接。 ORDER BY和LIMIT按字母顺序选择母语或第一语言。注意,没有真正的“第一”语言,SQL没有记录顺序,所以你需要使用ORDER BY来赋予“第一”的含义。
SELECT p.ID,
p.Name,
p.phone,
p.email,
l.Language,
l.Native
FROM people as p,
LEFT OUTER JOIN
(SELECT ID, Language, Native
FROM Languages
ORDER BY CASE WHEN Native THEN 0 ELSE 1 END, Language
LIMIT 1) as l
ON p.ID = l.ID
我没有测试过这个,但方法是正确的。如果它有问题请告诉我,我会更新语法。