我有以下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表中的数据相加并具有以下条件
ocardtype
为空,则忽略numitems
并将其视为0
在总和中将被忽略的项目汇总到ignoreditems
列ocardtype
是万事达卡或Visa,odate
是
为空,然后忽略numitems
并将其视为0
并将其相加
忽略了ignoreditems
列numitems
总和
不检查odate
,因为这些类型不需要odate
orderids
即使上面的3个条件是满意的,也要忽略到目前为止,查询工作完全归功于@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吗?
答案 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}},其中catalogid
为check
以累积每个True
。可能有一个更有效的解决方案(使用一些,可能是复杂的Linq-to-Sql,导致生成的SQL执行相当于orderidcollection
,或者使用Linq-to-Sql获取String.Join
然后使用Linq-to-objects进行最终累积。)
另请注意,此查询包含您的catalogid, numitems, check, orderid
表(LINQpad的复数形式)。