TSQL选择一个或多个行加入(TSQL select one or many rows to joi

2019-09-16 17:03发布

这是类似的问题: TSQL接一个地从2个条件选择行 ,但在这我想有个结果是不同的

我有一个表,如下所示:

ORDER_ID   CODE1   CODE2   CODE3   STATUS    TYPE        SUM      GROUP
1          '001'   'BIGP'  NULL    4         'company'   120      48
2          '002'   'BIGP'  NULL    1         'priv'      100      20
3          '001'    NULL   NULL    6         'priv'      50       49
4          '002'    NULL   'L'     1         'company'   1253     22

和第二表格如下所示:

ADDRESS_ID   ORDER_ID   ZIP       TYPE   ADD_DATE       CATEGORY     VERIFIED
1            1          '15-125'    'K1'   '2010-01-01'   'CLIENT'     1
2            1          '22-022'    'D1'   '2010-01-02'   'SYSTEM'     1
3            2          '16-159'    'D2'   '2010-01-02'   'SYSTEM'     1
4            2          '15-125'    'D2'   '2010-02-01'   'CLIENT'     0

第三和第四表包含像这样邮政编码和城市名称:

ZIP       CITY
'15-125'    'Warszawa'
'22-022'    'Koszalin'
'16-159'    'Krakow'
'15-125'    'Lublin'

对于具有每一份订单

  • 状态不是在(4,6)
  • 编码1“002”和“005”之间
  • (代码2 = null并且CODE3 = NULL)或(在( 'BIGA', 'BIGP' 码2)和CODE3 = NULL)或(码2 = NULL和CODE3 = 'L')

如果代码1 =“002” AND组(48,59,60,87),我必须选择一个地址
(非常感谢尼古拉Markovinović):

SELECT TOP 1000 o.order_Id
              , a.Address_Id
              , a.Zip
            --, *
FROM orders o
CROSS APPLY
(
 select TOP 1
        a.Address_Id,
        a.Zip
   from address a
  WHERE a.order_Id = o.order_Id
  ORDER BY case a.Type 
                when 'D2' then 1 
                when 'K1' then 2 
                else 3 
            end,
        a.ADD_DATE
) a
WHERE
 o.Status NOT IN (4, 6)
 AND code1='002'
 AND group IN (48,59,60,87)
 AND ((code2 IS NULL AND code3 IS NULL) OR (code2 IN ('BIGA', 'BIGP') AND code3 IS NULL) OR (code2 IS NULL AND code3 = 'L'))

为了满足顶级标准,并得到了代码1 =“002” AND组不是在所有其他命令(48,59,60,87),我必须选择已经验证= 1这些订单中的所有地址

收集这些地址后,我将能够检查是否有特定的帖子公司可以提供我的邮件到这些地址(我将检查在另一张表含邮政编码)

我在想使工会所有,采取先选择和做工会与第二,将返回所有的地址编码1 =“002” AND组NOT IN(48,59,60,87)。

但是,也许有可能做没有UNION ALL?

这一点,最后的结果我想获得:

CODE1        TYPE        COUNT_OF_ORDERS        COUNT_OF_ADDRESSES     COMPANY1  OTHER
'001'        'NORMAL'    125                    150                    110       40
'002'        'NORMAL'    100                    122                    100       22
'003'        'NORMAL'    150                    110                    100       10
'004'        'NORMAL'    200                    220                    220       0
'005'        'NORMAL'    220                    240                    210       30
'005'        'PRIORITY'  100                    110                    110       0
'SX1'        'PRIORITY'  100                    100                    20        80

所以,如果我喜欢的类型是“正常”我就要检查一下是否该地址顺序表存在具有正常的邮政编码,如果它的类型是“优先”我必须表检查与优先级代码。

如果在特定的表中存在的代码我加+1到公司1列,如果不是到其他,所以这些列的那笔一定是我的地址的总和。


这是查询,我已经成功地做到(与@NikolaMarkovinović的帮助)

SELECT TOP 1000 o.order_Id
              , a.Address_Id
              , a.Zip
            --, *
FROM orders o
CROSS APPLY
(
 select TOP 1
        a.Address_Id,
        a.Zip
   from address a
  WHERE a.order_Id = o.order_Id
    AND code1='002'
    AND o.[group] IN (48,59,60,87)
  ORDER BY case a.Type 
                when 'D2' then 1 
                when 'K1' then 2 
                else 3 
            end,
        a.ADD_DATE
  UNION ALL
 select 
        a.Address_Id,
        a.Zip
   from address a
  WHERE a.order_Id = o.order_Id
    AND ((code1='002' AND o.[group] NOT IN (48,59,60,87)) OR code1 IN ('001', '003', '004', '005'))
    --I'm not shure of that top line, it work's but mayby it con de written better
    AND Verified = 1
) a
WHERE
 o.Status NOT IN (4, 6)
 AND ((code2 IS NULL AND code3 IS NULL) 
    OR (code2 IN ('BIGA', 'BIGP') AND code3 IS NULL) 
    OR (code2 IS NULL AND code3 = 'L'))

Answer 1:

你可能很容易过滤地址( [group] IN (48,59,60,87) OR Verified = 1)但调整TOP 1会使事情荒谬( TOP (case when [group] IN (48,59,60,87) then 1 else (select count(*) from addresses where order_Id = o.order_Id) end) ,所以我建议你做的union all ,但只有不会忽略:

SELECT TOP 1000 o.order_Id
              , a.Address_Id
              , a.Zip
            --, *
FROM orders o
CROSS APPLY
(
 select TOP 1
        a.Address_Id,
        a.Zip
   from address a
  WHERE a.order_Id = o.order_Id
    AND o.[group] IN (48,59,60,87)
  ORDER BY case a.Type 
                when 'D2' then 1 
                when 'K1' then 2 
                else 3 
            end,
        a.ADD_DATE
  UNION ALL
 select 
        a.Address_Id,
        a.Zip
   from address a
  WHERE a.order_Id = o.order_Id
    AND o.[group] NOT IN (48,59,60,87)
    AND Verified = 1
) a
WHERE
 o.Status NOT IN (4, 6)
 AND code1='002'
 AND ((code2 IS NULL AND code3 IS NULL) 
    OR (code2 IN ('BIGA', 'BIGP') AND code3 IS NULL) 
    OR (code2 IS NULL AND code3 = 'L'))

PS。如果顺序可能没有地址替换CROSS与OUTER应用应用。



文章来源: TSQL select one or many rows to join