TSQL选择要联接的一行或多行

TSQL选择要联接的一行或多行,tsql,sql-server-2005,Tsql,Sql Server 2005,这个问题类似于:,但我希望得到的结果不同 我有一张这样的桌子: 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

这个问题类似于:,但我希望得到的结果不同

我有一张这样的桌子:

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
第二张表是这样的:

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中 “002”和“005”之间的代码1 code2=null和code3=null或“BIGA”、“BIGP”和code3=null中的code2或code2=null和code3=L 如果code1='002'和分组在48,59,60,87中,我必须选择一个地址 非常感谢尼古拉·马尔科维诺维奇:

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'))
对于符合top标准且代码为1='002'且组不在48,59,60,87中的所有其他订单,我必须为已验证=1的订单选择所有地址

收集完这些地址后,我将能够检查特定的邮政公司是否可以将我的邮件发送到这些地址,我将在另一个包含邮政编码的表中进行检查

我在考虑创建union all,使用第一个select并使用第二个进行union,这将返回code1='002'和组的所有地址,而不是48,59,60,87

但也许没有工会也能做到这一点

这是我希望得到的最终结果:

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添加到COMPANY1列,若不添加到OTHER列,那个么这些列的和必须是我的地址的和

这是我在@Nikola 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
    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'))

您可能很容易过滤48,59,60,87中的[group]地址或Verified=1,但如果48,59,60,87中的[group]地址为[group],则调整TOP 1会使情况变得荒谬,否则1会从order_Id=o.order_Id结束的地址中选择count*。因此,我建议,除地址外,您不必进行联合:

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'))

注意:如果订单可能没有地址,则用外部应用替换交叉应用。

分组方式,使用聚合函数MAX、MIN、SUM等。这是一种有趣的方法,但正如我在问题中所写的,我必须选择代码1在001和005之间的所有订单,但当code1='002'和group为48,59,60,87时,我必须只选择一个地址,在所有其他情况下,我必须选择已验证为=1的所有地址。所以可能存在这样的情况,订单的代码为1=002,但它有48,59,60,87以外的其他组,所以对于该订单,我必须获取所有已验证的地址。我将尝试调整您的查询并发布:@Misiu很好,谢谢。我的头脑无法消化所有这些抄本是空的或抄本在。。。复杂的情况下,所以我只是离开他们,因为他们是和集中在地址检索问题。昨天是漫长的一天:-再次感谢你:你真的很有技能,希望有一天我也会有这样的技能: