SQL Server 2008 - 用于连接字符串的字段

时间:2013-05-10 04:21:49

标签: sql-server-2008 concatenation

我正在运行以下脚本,但是连接字段返回的值不正确。

select customer_no, card_no, count(*) as no_trans,
stuff((select ',' + CAST(trans_id as varchar(20))
     from transactions a (nolock)
     where a.customer_no = b.customer_no and a.card_no = b.card_no
     for xml path('')),1,1,'') AS trans_ids
from transactions b (nolock)
where date>= '01 apr 2013'
and date < '30 apr 2013'
and trans_id in (select trans_id
          from product_items (nolock)
          where product_item in ('298029'))
group by customer_no, card_no

我期待得到的是否定的。 trans(count(*)),其中包含product_item,并将trans_id列表作为连接字段返回。

例如

customer_No            card_no        no_trans           trans_ids
1234                   12345          2                  1, 2

但我得到的是;

customer_No            card_no        no_trans           trans_ids
1234                   12345          2                  1, 2, 3, 5, 6

有人可以告诉我我做错了什么吗? 提前谢谢。

样本数据

交易表

Customer_No         Card_No        Trans_ID
1234                12345          1
1234                12345          2

产品项目表

Trans_ID        Product_item
1               298029
2               298029

1 个答案:

答案 0 :(得分:1)

我猜您的问题是,您还需要在查询的product_items部分中对for xml进行过滤。您可以通过使用CTE来查询所需的行transactions,然后使用CTE连接Trans_ID

这是一个SQL小提琴,其中包含一些示例数据,显示我认为是您的问题以及使用CTE进行的查询,该查询可以执行您想要的操作。

SQL Fiddle

MS SQL Server 2008架构设置

create table transactions
(
  Customer_No int,
  Card_No int,
  Trans_ID int
)

create table product_items
(
  Trans_ID int,
  Product_item int
)

insert into transactions values
(1234, 12345, 1),
(1234, 12345, 2),
(1234, 12345, 3),
(1234, 12345, 4),
(1234, 12345, 5)

insert into product_items values
(1, 298029),
(2, 298029),
(3, 298020),
(4, 298020),
(5, 298020)

查询1

-- Your query
select customer_no, card_no, count(*) as no_trans,
stuff((select ',' + CAST(trans_id as varchar(20))
     from transactions a (nolock)
     where a.customer_no = b.customer_no and a.card_no = b.card_no
     for xml path('')),1,1,'') AS trans_ids
from transactions b (nolock)
where trans_id in (select trans_id
                   from product_items (nolock)
                   where product_item in ('298029'))
group by customer_no, card_no

<强> Results

| CUSTOMER_NO | CARD_NO | NO_TRANS | TRANS_IDS |
------------------------------------------------
|        1234 |   12345 |        2 | 1,2,3,4,5 |

查询2

-- Rewritten to use a CTE
with C as
(
  select T.Customer_No, 
         T.Card_No,
         T.Trans_ID
  from transactions as T
  where T.Trans_ID in (select P.Trans_ID
                       from product_items as P
                       where P.Product_Item in ('298029'))
)
select C1.Customer_No,
       C1.Card_No,
       count(*) as No_Trans,
       stuff((select ',' + cast(C2.Trans_ID as varchar(20))
              from C as C2 
              where C1.Card_No = C2.Card_No and
                    C1.Customer_No = C2.Customer_No
              for xml path('')), 1, 1, '') as Trans_IDs
from C as C1
group by C1.Customer_No, 
         C1.Card_No

<强> Results

| CUSTOMER_NO | CARD_NO | NO_TRANS | TRANS_IDS |
------------------------------------------------
|        1234 |   12345 |        2 |       1,2 |