【问题标题】:SQL joining 2 queries that share a columnSQL 连接 2 个共享列的查询
【发布时间】:2012-10-03 14:40:37
【问题描述】:

我有 2 个 SQL 查询共享一个名为 catalogid 的列

查询 #1:

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) then numitems
                else 0 end) numitems,
 sum(numitems) allitems
from orders o"
join oitems i on i.orderid=o.orderid"
join products T1 on T1.catalogid = i.catalogid"
group by i.catalogid) X 

查询 #2:

SELECT catalogId, ProcessedSucssessfully =
       STUFF((SELECT ', ' + CAST( b.orderid as varchar(10))
              FROM oitems b JOIN orders o ON b.orderid = o.orderid
              WHERE b.catalogId = a.catalogId
              AND (o.ocardtype in ('PayPal','Sofort') OR o.ocardtype in  ('mastercard','visa') and o.odate is not null)
              FOR XML PATH('')), 1, 2, ''),
                  NotProcessed =
        STUFF((SELECT ', ' + CAST( c.orderid as varchar(10))
               FROM oitems c JOIN orders o ON c.orderId = o.orderid
               WHERE c.catalogid = a.catalogid
               AND (o.ocardtype in ('mastercard') OR o.ocardtype is null) and o.odate is null
               FOR XML PATH('')), 1, 2, '')
FROM oitems a
GROUP BY a.CatalogId

您如何将这 2 个查询合并为一个查询或加入它们?

请注意,我从 vb.net 以 SqlCommand 运行这 2 个

需要注意的一点是,我对两个查询的条件相同,我尝试将第二个查询部分添加到未解决的选择案例中

这里是涉及的表格

项目表

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

查询 #1 的结果:

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

查询 #2 的结果:

+-----------+------------------------+--------------+
| catalogid | ProcessedSucssessfully | NotProcessed |
+-----------+------------------------+--------------+
|       353 |o737,o739               |              |
|       364 |o738,o740               |              |
|       882 |o741                    |              |
|       224 |                        |o742,o743     |
+-----------+------------------------+--------------+

想要的结果:

+-----------+-----------+--------------+-------------------------+---------------+
| catalogid | numitems  | ignoreditems | ProcessedSucssessfully  | NotProcessed  |
+-----------+-----------+--------------+-------------------------+---------------+
|       353 |         4 |            0 | o737,o739               |               |
|       364 |        10 |            0 | o738,o740               |               |
|       882 |         2 |            0 | o741                    |               |
|       224 |         0 |            7 |                         | o742,o743     |
+-----------+-----------+--------------+-------------------------+---------------+

Query1的条件:

  1. 如果ocardtype 为空,则忽略numitems 并将其视为总和中的0,并将忽略的项目与ignoreditems 列相加

  2. 如果某些订单的 ocardtype 是 MasterCard 或 Visa,并且 odate 为空,则忽略 numitems 并将其视为 0,并将忽略的项目相加到 ignoreditems

  3. 如果 ocardtype 是 Paypal 或 Sofort,则只需对 numitems 求和而不检查日期,因为这些类型不需要 odate

Query2的条件与Query1相同,但要做的事情不同:

  1. 如果ocardtype 为空,则将orderid 添加到NotProcessed

  2. 如果某个订单的ocardtype 是万事达卡或维萨卡,而odate 为空,则将orderid 添加到NotProcessed

  3. 如果ocardtype 是Paypal 或Sofort,则不要检查odate 并将orderid 添加到ProcessedSucssessfully

上述事情是在 2 个单独的查询中完成的,但我试图将其纳入一个查询,因为它们具有相同的条件

【问题讨论】:

  • @RedFilter 我尝试将查询 2 的部分添加到 query1 的选择案例中,因为它们具有相同的条件但没有运气

标签: sql sql-server join sql-server-2008-r2 select-case


【解决方案1】:

您可以在 sql 框上创建一个视图,然后直接 Linq 到该视图

select * from table_a inner join table_b on table_a.field_a = table_b.field_b

编辑:

Select * from (select * from table_a inner join table_b on table_a.field_a = table_b.field_b) AB
inner join
select * from (select * from table_c inner join table_d on table_c.field_c = table_d.field_d) CD
ON
AB.id_column = CD.id_column

【讨论】:

  • 欢迎使用 StackOverflow:如果您发布代码、XML 或数据示例,在文本编辑器中突出显示这些行并单击“代码示例”按钮 ({ } ) 在编辑器工具栏上很好地格式化和语法突出显示它!
  • @thor 两个查询共享相同的条件,但我不确定如何将第二个 Query#2 部分添加到 Query#1 中的 select 语句中,尝试这样做但出现语法错误
  • 你能不能编写涉及的表并把 SQL 放上去
【解决方案2】:

好的,我们开始吧,我构建了表结构来验证 SQL。 我没有加载任何数据,但它确实执行了。

SELECT * FROM
(
Select  
   catalogid, numitems, allitems - numitems ignoreditems 
from 
    (
        select  
            i.catalogid, 
            case 
                when ocardtype in ('PayPal','Sofort') then sum(i.numitems)
                when ocardtype in ('mastercard','visa') and odate is not null then sum(i.numitems)
            else 0 end numitems, 
            sum(numitems) allitems 
        from 
            orders o
        inner join
            oitems i 
        on 
            i.orderid=o.orderid
        inner join 
            products T1 
        on 
            T1.catalogid = i.catalogid
        group by 
            i.catalogid, ocardtype, odate
    ) A
) B
INNER JOIN
(
    SELECT 
        catalogId, 
        ProcessedSucssessfully = 
           STUFF((SELECT ', ' + CAST( b.orderid as varchar(10)) 
                  FROM oitems b JOIN orders o ON b.orderid = o.orderid 
                  WHERE b.catalogId = a.catalogId 
                  AND (o.ocardtype in ('PayPal','Sofort') OR o.ocardtype in  ('mastercard','visa') and o.odate is not null) 
                  FOR XML PATH('')), 1, 2, ''), 
                      NotProcessed = 
            STUFF((SELECT ', ' + CAST( c.orderid as varchar(10)) 
                   FROM oitems c JOIN orders o ON c.orderId = o.orderid 
                   WHERE c.catalogid = a.catalogid 
                   AND (o.ocardtype in ('mastercard') OR o.ocardtype is null) and o.odate is null 
                   FOR XML PATH('')), 1, 2, '') 
    FROM 
        oitems a 
    GROUP BY 
        a.CatalogId 
)C
    ON 
        B.CatalogId = C.CatalogId

【讨论】:

  • 现在如果你想让它成为一个存储过程...添加到 sql 的顶部创建过程 usp_procedure_name (@OID VARCHAR(50)) AS 然后在每个部分添加一个 where 子句sql
  • 非常感谢,现在一切都好 :)
【解决方案3】:

SQL 服务器视图看起来像这样

SELECT * FROM
(
    Select  
       catalogid, numitems, allitems - numitems ignoreditems 
    from 
        (
        select * from
        (
            select  
                i.catalogid, 
                sum(case when (ocardtype in ('PayPal','Sofort') 
                OR 
                ocardtype in ('mastercard','visa') and odate is not null) then numitems 
                else 0 end) numitems, 
                sum(numitems) allitems 
            from 
                orders
         ) o
        inner join
            items i 
        on 
            i.orderid=o.orderid
        inner join 
            products T1 
        on 
            T1.catalogid = i.catalogid
        group by 
            i.catalogid
        ) A
    ) X 
) B
INNER JOIN
SELECT * FROM
(
    SELECT 
        catalogId, 
        ProcessedSucssessfully = 
           STUFF((SELECT ', ' + CAST( b.orderid as varchar(10)) 
                  FROM oitems b JOIN orders o ON b.orderid = o.orderid 
                  WHERE b.catalogId = a.catalogId 
                  AND (o.ocardtype in ('PayPal','Sofort') OR o.ocardtype in  ('mastercard','visa') and o.odate is not null) 
                  FOR XML PATH('')), 1, 2, ''), 
                      NotProcessed = 
            STUFF((SELECT ', ' + CAST( c.orderid as varchar(10)) 
                   FROM oitems c JOIN orders o ON c.orderId = o.orderid 
                   WHERE c.catalogid = a.catalogid 
                   AND (o.ocardtype in ('mastercard') OR o.ocardtype is null) and o.odate is null 
                   FOR XML PATH('')), 1, 2, '') 
    FROM 
        oitems a 
    GROUP BY 
        a.CatalogId 
) B
ON A.CatalogId = B.CatalogId

【讨论】:

  • 非常感谢,但它在 ) 和附近给了我语法错误,我认为这是因为我们有 24 '(' 和 25 ')' )(31,1) 预期令牌:未知)(31,1) 预期令牌:ON(54,1) 预期令牌:;加入 ( )
  • 可能是,我没有针对表结构进行验证。抱歉回复慢。昨天我不得不早早地跑步。
  • 没问题 感谢您花时间写它,我一直试图找出语法有什么问题,但无法弄清楚
猜你喜欢
  • 1970-01-01
  • 2021-07-18
  • 2013-03-03
  • 2016-08-21
  • 1970-01-01
  • 2013-10-16
  • 2020-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多