SQL查询,用于根据别名值

时间:2018-03-15 17:47:34

标签: sql sql-server tsql

如果我在此问题中未能使用正确的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值,即使是作为子查询。

非常感谢。

3 个答案:

答案 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;

查询的其余部分只是joinorders。您在问题中指定您知道如何做到这一点。

实际上,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