2012-04-24 41 views
3

这是类似的问题:TSQL select rows by one from 2 conditions,但它是在我想有结果不同TSQL选择一个或多个行加入

我有一个表像这样:

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' 

对于具有

  • 状态每顺序不在 '002' 之间(4,6)
  • 代码1和 '005'
  • (码2 = null并且CODE3 = NULL)或(如果code1 ='002'AND group IN(48,59,60,code3 = null)或(code2 = NULL且code3 ='L')中的代码2

如果code1 ='002' 87)我必须选择一个地址
(非常感谢尼古拉马尔科维诺VIC):

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组NOT IN(48,59,60,87),我必须选择的所有地址已经验证了这些订单中的所有其他订单= 1

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

我在想使工会所有,首先选择并与第二个联合,返回code1 ='002'和组NOT IN(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 

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

如果代码存在于特定表格中,我向COMPANY1列添加+1,如果不是OTHER,则这些列的总和必须是我的地址的总和。


这是查询,我已经成功地做到(与@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')) 
+0

GROUP BY,具有集合函数MAX,MIN,SUM等...... – Ben 2012-04-24 12:36:54

回答

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与OUT APPLY ER适用。

+0

这是一个有趣的方式,但是当我在写我的问题时,我必须选择001和005之间的code1的所有顺序,但当code1 ='002'和group in(48,59,60,87)时,我只能选择一个地址,在所有其他情况下,我必须选择已验证= 1的所有地址。所以可能会出现这样的情况,即订单有code1 = 002,但是它有另一个组(48,59,60,87),所以对于该订单,我必须采取所有经过验证的地址。我会尽力调整你的查询并发布:) – Misiu 2012-04-25 06:13:10

+0

@Misiu太好了,谢谢。我的思想无法消化所有'codex在复杂条件下为空或代码性状态,所以我只是将它们留在原来的位置,并集中在地址检索问题上。昨天是漫长的一天:-) – 2012-04-25 07:43:45

+0

再次谢谢你:)你真的有技能,希望有一天我会拥有如此的技能:) – Misiu 2012-04-25 08:12:07