Sql 需要同一行中有2个地址的客户列表

Sql 需要同一行中有2个地址的客户列表,sql,sql-server,sql-server-2008,tsql,Sql,Sql Server,Sql Server 2008,Tsql,我正试图从数据库中提取所有客户信息。此结果集的一部分将是地址列 我有一个用户表和地址表。地址表为每个用户保存0个地址。我只需要为每个用户创建的最后2个 到目前为止,我有一个查询,它返回所有客户数据,与region表联接以获取货币名称,与orders联接以获取该用户的已发货订单总数 SELECT ( CASE WHEN u.password IS NULL THEN 'GUEST' ELSE 'CUSTOMER' END )

我正试图从数据库中提取所有客户信息。此结果集的一部分将是地址列

我有一个用户表和地址表。地址表为每个用户保存0个地址。我只需要为每个用户创建的最后2个

到目前为止,我有一个查询,它返回所有客户数据,与region表联接以获取货币名称,与orders联接以获取该用户的已发货订单总数

SELECT ( CASE
           WHEN u.password IS NULL THEN 'GUEST'
           ELSE 'CUSTOMER'
         END )                                 AS STATUS,
       u.date_created                          AS DateCreated,
       u.NAME                                  AS UserName,
       u.password                              AS Password,
       u.email                                 AS Email,
       r.token                                 AS Currency,
       Cast(u.balance / 100 AS DECIMAL(10, 2)) AS Balance,
       Count(o.user_id)                        AS TotalShippedOrders
FROM   [db].[user] u
       INNER JOIN [db].[region] r
               ON r.currency_id = u.balance_currency
       LEFT JOIN [db].[order] o
              ON o.user_id = u.id
                 AND o.status = 'shipped'
GROUP  BY u.id,
          u.date_created,
          u.NAME,
          u.password,
          u.email,
          r.token,
          u.balance
ORDER  BY TotalShippedOrders DESC; 
address
表中有
user\u id、address、city、state等、date\u created

我不知道如何将地址表连接到上面的查询中,以便只获取同一行上的最后两个地址。我想在原始查询中添加以下列:

address1, city1, state1, address2, city2, state2
并且只使用该用户的最后2个地址填充这些地址


有人能给我指出一个如何表述这部分问题的方向吗?谢谢

在加入
用户
表之前,需要
透视
地址
表数据

;WITH address_cte -- Generate ROW_NUMBER to find the last two address for each user_id
     AS (SELECT Row_number()OVER(partition BY user_id
                    ORDER BY date_created DESC) AS rn,
                user_id,
                address,
                city,
                state
         FROM   address),
     address_pivot -- Pivot the address
     AS (SELECT user_id,
                Max(CASE WHEN rn = 1 THEN address END) AS address_1,
                Max(CASE WHEN rn = 1 THEN city END) AS city_1,
                Max(CASE WHEN rn = 1 THEN state END) AS state_1,
                Max(CASE WHEN rn = 2 THEN address END) AS address_2,
                Max(CASE WHEN rn = 2 THEN city END) AS city_2,
                Max(CASE WHEN rn = 2 THEN state END) AS state_2,
                COUNT(1) as Address_count
         FROM   address_cte
         GROUP  BY user_id)
SELECT ( CASE
           WHEN u.password IS NULL THEN 'GUEST'
           ELSE 'CUSTOMER'
         END )                                 AS STATUS,
       u.date_created                          AS DateCreated,
       u.NAME                                  AS UserName,
       u.password                              AS Password,
       u.email                                 AS Email,
       r.token                                 AS Currency,
       Cast(u.balance / 100 AS DECIMAL(10, 2)) AS Balance,
       Count(o.user_id)                        AS TotalShippedOrders,
       address_1,
       city_1,
       state_1,
       address_2,
       city_2,
       state_2,
       Address_count
FROM   [db].[user] u
       INNER JOIN [db].[region] r
               ON r.currency_id = u.balance_currency
       LEFT JOIN [db].[order] o
              ON o.user_id = u.id
                 AND o.status = 'shipped'
       LEFT JOIN address_pivot ap
              ON ap.user_id = u.user_id
GROUP  BY u.id,
          u.date_created,
          u.NAME,
          u.password,
          u.email,
          r.token,
          u.balance,
          address_1,
          city_1,
          state_1,
          address_2,
          city_2,
          state_2,
          Address_count
ORDER  BY TotalShippedOrders DESC; 

深入外部应用

;with [Users] as
(
  select 1 as id, 'jim' as name
  union all
  select 2, 'jane'
),
[Address] as
(
  select 1 as id, 1 as user_id, 'new york' as addr
  union all
  select 2, 2, 'tokio'
  union all
  select 3, 2, 'moscow'
  union all
  select 4, 2, 'paris'
  union all
  select 5, 2, 'london'
  union all
  select 6, 2, 'canberra'
)
select u.*, a.addr
from [Users] u
outer apply
(
  select
    stuff(cast((
      select top 2
        ', ' + a.addr 
      from [Address] a
      where a.user_id = u.id
      order by a.id desc
      for xml path('')
     ) as varchar(8000)), 1, 2, '') as addr
) a

top 2
和串联

为什么轴中的
Max
?@VR46这太棒了!我将通过谷歌数据透视来找出代码背后的逻辑。如何添加另一列,该列包含每个用户的地址总数?@xMetalDetectorx-更新了答案以获取每个用户的地址总数user@MotoGP-我很感激!但它看起来只给出了2个最大计数,而不是每个地址的总数量user@xMetalDetectorx-我已从地址组(按用户id)中删除此处的where条件
。请执行上述查询并检查