如果我在此问题中未能使用正确的SQL术语/方法,请提前致歉。我要做的是为电子商务系统编写SQL查询(使用SQL Server 2008R2),该系统将整理来自一个表的订单数据和来自第二个表的客户数据。我的SQL技能到目前为止JOIN
,我相当肯定这将涉及更全面的更像子查询,因为客户数据存储不是(我称之为)直接。我不确定采取什么方法。
注意,这是第三方系统,所以我无法控制数据库架构。
我有两张桌子:
订单:
OrderId | OrderValue
--------------------
1 | 123
2 | 338
3 | 500
CustomerData :
OrderId | Alias | Value
-------------------------------
1 | firstName | John
1 | lastName | Smith
1 | city | Boston
1 | zip | 12345
1 | address1 | Someplace
2 | firstName | Jane
2 | lastName | Doe
2 | city | New Orleans
2 | zip | 23456
2 | address1 | 1 Brookland Avenue
3 | firstName | Eric
3 | lastName | Black
3 | city | Chicago
3 | zip | 34567
3 | address1 | Apartment 356
我需要做的是生成一个查询以输出以下内容:
OrderId | OrderValue | FirstName | LastName | Address
------------------------------------------------------------------------------------
1 | 123 | John | Smith | Someplace, Boston, 12345
2 | 338 | Jane | Doe | 1 Brookland Avenue, New Orleans, 23456
3 | 500 | Eric | Black | Apartment 356, Chicago, 34567
'Address'字段需要由CustomerData表中的值组成,其中Alias值为'address1','city'和'zip',并以逗号分隔的字符串形式连接。这些字段将始终存在于CustomerData表中,但不一定按相同的顺序排列,并且不会按输出数据集中所需的顺序排列 - 因此我需要显式连接他们是'address1,city,zip'。
我正在努力解决需要根据别名字段选择CustomerData值的事实,它们不是表格列,这会使生活变得更加简单。
有人可以建议如何解决这个问题吗?我没有创建起始查询的事实不是由于懒惰或缺乏意愿,我真的不确定如何正确获取这些CustomerData值,即使是作为子查询。
非常感谢。
答案 0 :(得分:2)
这是您总结customers
:
select orderid,
max(case when alias = 'firstName' then value end) as firstname,
max(case when alias = 'lastName' then value end) as lastname,
(max(case when alias = 'address1' then value end) + ',' +
max(case when alias = 'city' then value end) + ',' +
max(case when alias = 'zip' then value end)
) as address
from customers c
group by orderid;
查询的其余部分只是join
到orders
。您在问题中指定您知道如何做到这一点。
实际上,orders
可能有点棘手:
select c.orderid, o.ordervalue,
max(case when c.alias = 'firstName' then c.value end) as firstname,
max(case when c.alias = 'lastName' then c.value end) as lastname,
(max(case when c.alias = 'address1' then c.value end) + ',' +
max(case when c.alias = 'city' then c.value end) + ',' +
max(case when c.alias = 'zip' then c.value end)
) as address
from customers c join
orders o
on o.orderid = c.orderid
group by o.orderid, o.ordervalue;
编辑:在第二个查询的第一行末尾添加了一个逗号
答案 1 :(得分:1)
看起来您只需要转移客户数据,然后从订单
加入select o.OrderId,
o.OrderValue,
cd.[firstName],
cd.[lastName],
coalesce([address1] + ', ','') +
coalesce([city] + ', ','') +
coalesce([zip],'') as Address
from orders o
left join ( select *
from CustomerData
pivot (
max(Value)
for Alias in ([firstName],[lastName],[address1],[city],[zip])
) p
) cd on o.OrderId = cd.OrderId
答案 2 :(得分:0)
这是基于join
的。它可能更有效率。
declare @O table(id int primary key, val int);
insert into @O values
(1, 123)
, (2, 338)
, (3, 500);
declare @C table(oid int, alias varchar(20), val varchar(20));
insert into @C values
(1, 'firstName', 'John')
, (1, 'lastName', 'Smith')
, (1, 'city', 'Boston')
, (1, 'zip', '12345')
, (1, 'address1', 'Someplace')
, (2, 'firstName', 'Jane')
, (2, 'lastName', 'Doe')
, (2, 'city', 'New Orleans')
, (2, 'zip', '23456')
, (2, 'address1', '1 Brookland Avenue')
, (3, 'firstName', 'Eric')
, (3, 'lastName', 'Black')
, (3, 'city', 'Chicago')
, (3, 'zip', '34567')
, (3, 'address1', 'Apartment 356');
select o.id as orderId, o.val as orderValue
, cF.val as firstName, cl.val as lastName
--, cC.val as city, cZ.val as zip, cA.val as address1
, cC.val + ', ' + cZ.val + ', ' + cA.val as address
from @O o
join @C cF
on cF.oid = o.id
and cF.alias = 'firstName'
join @C cL
on cL.oid = o.id
and cL.alias = 'lastName'
join @C cC
on cC.oid = o.id
and cC.alias = 'city'
join @C cZ
on cZ.oid = o.id
and cZ.alias = 'zip'
join @C cA
on cA.oid = o.id
and cA.alias = 'address1'
order by o.id;
orderId orderValue firstName lastName address
----------- ----------- -------------------- -------------------- ----------------------------------------------------------------
1 123 John Smith Boston, 12345, Someplace
2 338 Jane Doe New Orleans, 23456, 1 Brookland Avenue
3 500 Eric Black Chicago, 34567, Apartment 356