2017-04-26 114 views
3

我在StackOverflow和Internet上搜索过,但没有找到任何解决此问题的方法。 我有一个像SQL Server 2008 R2中的myTable这样的表格: person_id,city,addressTypeline_numtextarea和一些其他列,但这些都不是必需的。 所有字段的类型为int,但textarea的类型为varchar(10)。 一个人可以在一个城市中拥有多种类型的地址。地址可以很大,因此每个地址类型可以有多个行号。地址类型1是家庭地址,地址类型2是办公地址,地址类型3是其他地址。 示例行此处给出SQL查询显示多个连接在同一个表上的错误

person_id|city|addressType|line_num|textarea 
1  |1 |1   |0  |House no. 
--------------------------------------------- 
1  |1 |1   |1  |10 
--------------------------------------------- 
1  |1 |2   |0  |Building5 
--------------------------------------------- 
1  |1 |2   |1  |Floor 1 
--------------------------------------------- 
1  |1 |3   |0  |Factory 
--------------------------------------------- 
1  |1 |3   |1  |no. 30 

我需要表现出一个人的所有类型的地址在一个row.Like这样的:

person_id|city|homeAddress |officeAddress |otherAddress 
1  |1 |House no.,10|Building5,Floor 1|Factory,no.30 

我曾经加入。 加入地址类型1和地址类型2

这里工作得很好是单一加入的是工作的罚款查询:

SET ANSI_PADDING ON; 
SELECT DISTINCT homeAddress_person_id, homeAddress_city, homeAddress, officeAddress 
FROM 
/*Sub query for home address*/ 
(SELECT person_id AS homeAddress_person_id, city AS homeAddress_city, 
/*Concatinating home address*/ 
STUFF((SELECT ',' + textarea FROM myTable WHERE person_id=ResultsFrom_myTable_For_homeAddress.person_id AND city=ResultsFrom_myTable_For_homeAddress.city AND addressType=ResultsFrom_myTable_For_homeAddress.addressType FOR XML PATH(''),TYPE).value('.','VARCHAR(4000)'),1,1,'') AS homeAddress 
FROM myTable ResultsFrom_myTable_For_homeAddress WHERE person_id=1 AND addressType=1 
GROUP BY person_id,city,addressType) ResultsFrom_myTable_For_homeAddress_outer 

FULL OUTER JOIN 
/*Sub query for office address*/ 
(SELECT person_id AS officeAddress_person_id, city AS officeAddress_city, 
/*Concatinating office address*/ 
STUFF((SELECT ',' + textarea FROM myTable WHERE person_id=ResultsFrom_myTable_For_officeAddress.person_id AND city=ResultsFrom_myTable_For_officeAddress.city AND addressType=ResultsFrom_myTable_For_officeAddress.addressType FOR XML PATH(''),TYPE).value('.','VARCHAR(4000)') 
,1 
,1 
,'') AS officeAddress 
FROM myTable ResultsFrom_myTable_For_officeAddress 
WHERE person_id=1 AND addressType=2 
GROUP BY person_id,city,addressType) ResultsFrom_myTable_For_officeAddress_outer 
ON ResultsFrom_myTable_For_homeAddress_outer.homeAddress_person_id=ResultsFrom_myTable_For_officeAddress_outer.officeAddress_person_id AND ResultsFrom_myTable_For_homeAddress_outer.homeAddress_city=ResultsFrom_myTable_For_officeAddress_outer.officeAddress_city 
SET ANSI_PADDING OFF; 

但当我再添加入到显示其它地址。它显示错误了条件,预计 这里有两个联接的查询

SET ANSI_PADDING ON; 
SELECT DISTINCT homeAddress_person_id, homeAddress_city, homeAddress, officeAddress, otherAddress 
FROM 
/*Sub query for home address*/ 
(SELECT person_id AS homeAddress_person_id, city AS homeAddress_city, 
/*Concatinating home address*/ 
STUFF((SELECT ',' + textarea FROM myTable WHERE person_id=ResultsFrom_myTable_For_homeAddress.person_id AND city=ResultsFrom_myTable_For_homeAddress.city AND addressType=ResultsFrom_myTable_For_homeAddress.addressType FOR XML PATH(''),TYPE).value('.','VARCHAR(4000)'),1,1,'') AS homeAddress 
FROM myTable ResultsFrom_myTable_For_homeAddress WHERE person_id=1 AND addressType=1 
GROUP BY person_id,city,addressType) ResultsFrom_myTable_For_homeAddress_outer 

FULL OUTER JOIN 
/*Sub query for office address*/ 
(SELECT person_id AS officeAddress_person_id, city AS officeAddress_city, 
/*Concatinating office address*/ 
STUFF((SELECT ',' + textarea FROM myTable WHERE person_id=ResultsFrom_myTable_For_officeAddress.person_id AND city=ResultsFrom_myTable_For_officeAddress.city AND addressType=ResultsFrom_myTable_For_officeAddress.addressType FOR XML PATH(''),TYPE).value('.','VARCHAR(4000)') 
,1 
,1 
,'') AS officeAddress 
FROM myTable ResultsFrom_myTable_For_officeAddress 
WHERE person_id=1 AND addressType=2 
GROUP BY person_id,city,addressType) ResultsFrom_myTable_For_officeAddress_outer 
ON ResultsFrom_myTable_For_homeAddress_outer.homeAddress_person_id=ResultsFrom_myTable_For_officeAddress_outer.officeAddress_person_id AND ResultsFrom_myTable_For_homeAddress_outer.homeAddress_city=ResultsFrom_myTable_For_officeAddress_outer.officeAddress_city 

FULL OUTER JOIN 
/*Sub query for other address*/ 
(SELECT person_id AS otherAddress_person_id,city AS otherAddress_city, 
/*Concatinating office address*/ 
STUFF((SELECT ',' + textarea FROM myTable WHERE person_id=ResultsFrom_myTable_For_otherAddress.person_id AND city=ResultsFrom_myTable_For_otherAddress.city AND addressType=ResultsFrom_myTable_For_otherAddress.addressType FOR XML PATH(''),TYPE).value('.','VARCHAR(4000)'),1,1,'') AS otherAddress 
FROM myTable ResultsFrom_myTable_For_otherAddress WHERE person_id=1 AND addressType=3 
GROUP BY person_id,city,addressType) ResultsFrom_myTable_For_otherAddress_outer 
ON ResultsFrom_myTable_For_homeAddress_outer.homeAddress_person_id=ResultsFrom_myTable_For_otherAddress_outer.otherAddress_person_id AND ResultsFrom_myTable_For_homeAddress_outer.homeAddress_city=ResultsFrom_myTable_For_otherAddress_outer.otherAddress_city; 
SET ANSI_PADDING OFF; 

什么是错在上面的查询中指定的上下文非布尔类型的表达式?

+1

格式化您的查询,因此它会更好的可读性 – Jens

+0

@Jens查询格式化。现在这更易读吗? – Varun

回答

3

使用common table expression和有条件的聚集,我们最多可以清洁此查询并把它变成这样:

with cte as (
    select 
     person_id 
    , city 
    , addressType 
    , address = stuff((
     select ',' + i.textarea 
     from myTable i 
     where i.person_id = t.person_id 
      and i.city = t.city 
      and i.addressType = t.addressType 
     order by line_num 
     for xml path(''), type).value('.', 'varchar(4000)'), 1, 1, '') 
from MyTable as t 
group by person_id, city, addressType 
) 
select 
    t.person_id 
    , t.city 
    , homeAddress = max(case when t.addressType = 1 then t.address end) 
    , officeAddress = max(case when t.addressType = 2 then t.address end) 
    , otherAddress = max(case when t.addressType = 3 then t.address end) 
from cte as t 
where t.person_id = 1 
group by t.person_id, t.city 

rextester演示:http://rextester.com/RWIQ34896

回报:

+-----------+------+--------------+-------------------+----------------+ 
| person_id | city | homeAddress | officeAddress | otherAddress | 
+-----------+------+--------------+-------------------+----------------+ 
|   1 | 1 | House no.,10 | Building5,Floor 1 | Factory,no. 30 | 
+-----------+------+--------------+-------------------+----------------+ 

你的问题说, addressType 0是家庭,但您的查询是使用addressType 1.我相信您可以做出适当的调整以任何方式查询此查询。

+0

谢谢。地址类型1是家庭。问题已更新。 – Varun

+0

这很像魔术。你是救世主。我希望能给你10个upvotes。感谢让我学习新事物。 – Varun

+0

@Varun乐意帮忙! – SqlZim

相关问题