1

私はそれが何をするかを理解するために次の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テーブル

品目表

+---------+-----------+----------+
| 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 |
+-----------+----------+--------------+

アイデアは、次の条件を使用して、oitems テーブルのデータに基づいて、同じ catalogid を持つ製品の numitems 列を合計することです。

  1. ocardtypeが空の場合、無視し て合計numitemsと見なし、無視された項目を列に合計します0ignoreditems
  2. ocardtype一部の注文が MasterCard または Visa で、odateが空の場合、 を無視してとnumitems見なし、無視されたアイテムを列0に合計しますignoreditems
  3. ocardtype が Paypal または Sofort の場合、チェックせずに合計を計算するだけですnumitemsodateodate
  4. 予約済みという別のテーブルには、ignoredoid という列があり、この列にorderidsは、上記の 3 つの条件が満たされていても無視したい上記のテーブルが含まれています

この時点まで、@Richard aka Cyber​​kiwi のこの質問への回答のおかげで、クエリは完全に機能しています。


質問は、結果のデータテーブルが次のようになる必要があることです

+-----------+----------+--------------+-------------------+
| 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でも可能ですか?

4

1 に答える 1

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 クエリを発行して、orderidsfor eachがeach を累積するcatalogid場所を決定することに注意してください。より効率的な解決策があるかもしれません (おそらく複雑な Linq-to-Sql を使用して、生成された SQL が と同等の処理を行うか、 Linq-to-Sql を使用して取得し、Linq-to-objects を使用して実行します最終的な累積)。checkTrueorderidcollectionString.Joincatalogid, numitems, check, orderid

また、このクエリにはBookedテーブルが含まれていることに注意してください(LINQpadの複数形を使用)。

于 2012-10-02T11:37:25.697 に答える