SQL 加入 2 個共享列的查詢 (SQL joining 2 queries that share a column)


問題描述

SQL 加入 2 個共享列的查詢 (SQL joining 2 queries that share a column)

I have 2 SQL queries that share a column called catalogid

Query #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 

Query #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

How would you make those 2 into one query or join them?

Note I run those 2 as SqlCommand from vb.net

One thing to notice is i've the same conditions for both queries, what I tried doing is adding the second query parts to the select case which didn't work out

Here are the involved tables 

oitems table

+---------+-----------+----------+
| orderid | catalogid | numitems |
+---------+-----------+----------+
| o737    |       353 |        1 |
| o738    |       364 |        4 |
| o739    |       353 |        3 |
| o740    |       364 |        6 |
| o741    |       882 |        2 |
| o742    |       224 |        5 |
| o743    |       224 |        2 |
+---------+-----------+----------+

orders table

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

result from Query #1:

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

result from Query #2:

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

the wanted result:

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

The conditions for Query1:

  1. if ocardtype is empty then ignore the numitems and consider it as 0 in the sum and sum the ignored items to the ignoreditems column

  2. if ocardtype for some order is MasterCard or Visa and the odate is empty then ignore the numitems and consider it as 0 and sum the ignored items to the ignoreditems column

  3. if ocardtype is Paypal or Sofort, then just do the numitems sum without checking the date because those types require no odate

The conditions for Query2 Which are the same as Query1 but different things to be done:

  1. if ocardtype is empty then add orderid to NotProcessed

  2. if ocardtype for some order is MasterCard or Visa and the odate is empty then add orderid to NotProcessed

  3. if ocardtype is Paypal or Sofort, then don't check for odate and add the orderid to ProcessedSucssessfully

The above things are done in 2 seperate queries, but I am trying to make it in to one query since they have the same conditions


參考解法

方法 1:

You could create a view on the sql box and then just Linq to that view

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

EDIT:

or

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

方法 2:

SQL server view would look something like this

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

方法 3:

Ok here we go, I built out the table structure to validate the SQL. I did not load any data but it does execute.

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

(by user1570048Thor BurfineThor BurfineThor Burfine)

參考文件

  1. SQL joining 2 queries that share a column (CC BY-SA 3.0/4.0)

#select-case #sql-server-2008-r2 #SQL #sql-server #join






相關問題

SQL 加入 2 個共享列的查詢 (SQL joining 2 queries that share a column)

sql中的條件總和,根據字段中的條件從另一個表中獲取正確的總和 (conditional sum in sql, get correct sum from another table based on a condition in a field)

如何對此查詢進行選擇案例? (How can I do select case to this query?)

聲明一個案例列表在多個地方使用 (Declaring a case list to be used in more than one place)

選擇案例語句中的數組是否可能? (Is an array inside a select case statement possible?)

將 VBA 選擇案例轉換為 C# (Convert VBA select case to C#)

使用 Word VBA 中的宏選擇大小寫將英寸轉換為毫米 (Convert inch to mm using macro select Case in Word VBA)

訪問,選擇案例 ActiveControl.Name? (Access, Select Case ActiveControl.Name?)

選擇不運行每個案例的案例 (Select Case Not Running Every Case)

JustBasic,在代碼中出現“錯誤的嵌套錯誤選擇/案例” (JustBasic, getting "bad nesting error select/case" in code)







留言討論