我在StackOverflow和互联网上搜索过但没有找到任何解决方案。
我有一个像SQL Server 2008 R2中的myTable这样的表,包含以下列:
person_id
,city
,addressType
,line_num
,textarea
以及其他一些列,但不需要这些列。
所有字段都是int类型,但textarea的类型为varchar(10)。
一个人可以在一个城市拥有多种类型的地址。地址可以很大,因此每种地址类型可以有多个行号。地址类型1是家庭地址,地址类型2是办公室地址,地址类型3是其他地址。
这里给出了示例行
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
我需要在一行中显示所有类型的地址。就像这样:
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;
上述查询有什么问题?
答案 0 :(得分: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.我相信您可以对此查询进行适当的调整。