SQL将处理后的id添加到用逗号分隔的单个单元格中

时间:2012-10-01 13:34:40

标签: sql sql-server datatable sql-server-2008-r2 conditional

我有以下sql查询来了解它的作用请阅读下面的描述

select catalogid, numitems, allitems - numitems ignoreditems
    from (
      select i.catalogid,
        sum(case when (ocardtype in ('PayPal','Sofort') OR
                       ocardtype in ('mastercard','visa') and
                       odate is not null) AND NOT EXISTS (
                         select * from booked b
                         where b.ignoredoid = o.orderid
                       ) then numitems
                       else 0 end) numitems,
        sum(numitems) allitems
      from orders o
      join oitems i on i.orderid=o.orderid
      group by i.catalogid
    ) X

和以下sql表

oitems表

+---------+-----------+----------+
| orderid | catalogid | numitems |
+---------+-----------+----------+
| O737    |       353 |        1 |
| O738    |       364 |        4 |
| O739    |       353 |        3 |
| O740    |       364 |        6 |
| O741    |       882 |        2 |
| O742    |       224 |        5 |
| O743    |       224 |        2 |
+---------+-----------+----------+

订单表

 +-----------------+------------+------------+
    |         orderid | ocardtype  |   odate    |
    +-----------------+------------+------------+
    |     O737        | Paypal     |            | 'OK
    |     O738        | MasterCard | 01.02.2012 | 'OK
    |     O739        | MasterCard | 02.02.2012 | 'OK
    |     O740        | Visa       | 03.02.2012 | 'OK
    |     O741        | Sofort     |            | 'OK
    |     O742        |            |            | 'ignore because ocardtype is empty
    |     O743        | MasterCard |            | 'ignore because Mastercard no odate
    +-----------------+------------+------------+

重新声明的数据表

+-----------+----------+--------------+
| catalogid | numitems | ignoreditems |
+-----------+----------+--------------+
|       353 |        4 |            0 |
|       364 |       10 |            0 |
|       882 |        2 |            0 |
|       224 |        0 |            7 |
+-----------+----------+--------------+

想法是将具有相同catalogid描述的产品的numitems列与oitems表中的数据相加并具有以下条件

  1. 如果ocardtype为空,则忽略numitems并将其视为0 在总和中将被忽略的项目汇总到ignoreditems
  2. 如果某个订单的ocardtype是万事达卡或Visa,odate是 为空,然后忽略numitems并将其视为0并将其相加 忽略了ignoreditems
  3. 的项目
  4. 如果ocardtype是Paypal或Sofort,那么只需要numitems总和 不检查odate,因为这些类型不需要odate
  5. 在另一个叫做预订的表中我有一个名为ignoredoid的列, 这列包含我想要的上表中的orderids 即使上面的3个条件是满意的,也要忽略
  6. 到目前为止,查询工作完全归功于@Richard aka cyberkiwi对此问题的回答question


    问题是,我需要结果数据表看起来像下面的

    +-----------+----------+--------------+-------------------+
    | catalogid | numitems | ignoreditems | orderidcollection |
    +-----------+----------+--------------+-------------------+
    |       353 |        4 |            0 | O737,O739         |
    |       364 |       10 |            0 | O738,O740         |
    |       882 |        2 |            0 | O741              |
    |       224 |        0 |            7 |                   |'O742 & O743 are ignored      
    +-----------+----------+--------------+-------------------+
    

    正如您所看到的唯一更改是添加了orderidcollection列,只有在代码中未忽略该顺序时,才必须将orderid添加到由逗号分隔的新列中,我一直在谷歌搜索几个小时没有运气! 这甚至可以用SQL吗?

1 个答案:

答案 0 :(得分:1)

我的Linq-to-Sql对您之前的问题的回答扩展到此问题(LINQpad查询):

Dim odateRequired = {"MasterCard", "Visa"}
Dim odateNotRequired = {"Paypal", "Sofort"}

Dim result = From o In Orders Join i In Oitems On o.orderid Equals i.orderid _
             Let check = Not (From b In Bookeds Where b.ignoredoid=i.orderid).Any _
                     AndAlso o.ocardtype IsNot Nothing _
                     AndAlso ((odateRequired.Contains(o.ocardtype) AndAlso o.odate IsNot Nothing) _
                        OrElse odateNotRequired.Contains(o.ocardtype)) _
         Group By i.catalogid Into _
         numitems = Sum(If(check, i.numitems, 0)), _
         ignoreditems = Sum(If(check, 0, i.numitems)), _
         group
         Select catalogid, numitems, ignoreditems, _
             orderidcollection = String.Join(",", (From g in group Where g.check Select g.i.orderid))
result.Dump

请注意,此解决方案会发出多个SQL查询,以确定每个orderids的{​​{1}},其中catalogidcheck以累积每个True。可能有一个更有效的解决方案(使用一些,可能是复杂的Linq-to-Sql,导致生成的SQL执行相当于orderidcollection,或者使用Linq-to-Sql获取String.Join然后使用Linq-to-objects进行最终累积。)

另请注意,此查询包含您的catalogid, numitems, check, orderid表(LINQpad的复数形式)。