2016-06-09 65 views
0

我有以下查询的SQL Server 2014联盟CROSS APPLY

SELECT DISTINCT 
    d.UserName, 
    i.itemID, 
    d.Score, 
    d.StoreCode, 
    d.Location 
FROM 
    G.dbo.Users d 
LEFT JOIN 
    G.dbo.Emails s on d.UserName=s.UserName 
CROSS APPLY 
    (
     SELECT TOP (1) 
      ii.ItemID 
     FROM 
      G.dbo.Dump ii 
     WHERE 
      ii.Username=d.UserName 
     AND 
      ii.endTime>DATEADD(hh,3,getDate()) 
    ) i 
WHERE 
    s.serName is null 
AND 
    d.Score>@_Score 
AND 
    (d.processed=0) 
GROUP BY 
    d.UserName, 
    i.itemID, 
    d.Score, 
    d.StoreCode, 
    d.Location 
ORDER BY 
    d.UserName ASC 

现在我需要修改它,因为表G.dbo.Dump已经分裂成20个较小的表,现在我有Dump_00Dump_19
我试着以这种方式

CROSS APPLY 
(
    SELECT TOP (1) 
     ii.ItemID 
    FROM 
     (
      SELECT TOP (1) FROM G.dbo.Dump_00 
      UNION 
      SELECT TOP (1) FROM G.dbo.Dump_01 
      UNION 
      ..... 
      SELECT TOP (1) FROM G.dbo.Dump_19 
     ) ii 
    WHERE 
     ii.UserName=d.UserName 
    AND 
     ii.EndTime>DATEADD(hh,3,getDate()) 
) i 

但结果修改使用UNIONCROSS APPLY节的一部分,工作不正常

可以建议如果UNION是正确的方式,以及如何申请,或另一种解决方案?

谢谢!

+0

它应该返回什么?没有'ORDER BY'的'TOP 1'不保证任何特定的行。 –

+0

因此,我们也需要成为读者的头脑,要知道“不按预期工作”实际上是什么意思? –

+0

@MartinSmith它应该返回用户名和第一个(仍然有效)用户出现在卖家表中,但不在电子邮件表中。 关于TOP 1,是的,你说得对,但它已经足够了,它返回一个随机结果时间> DateAdd ...没有添加Order BY来减少处理时间,因为转储表已超过1亿个记录。 – Joe

回答

2

从联合元素中删除TOP 1。不知道为什么添加。从逻辑上讲,你是在所有表的联合集之后。

此外,我不认为你想要一个工会。你想要连接。

CROSS APPLY 
(
    SELECT TOP (1) ii.ItemID 
    FROM 
     (
      SELECT FROM G.dbo.Dump_00 --changed 
      UNION ALL --changed 
      SELECT FROM G.dbo.Dump_01 --changed 
      ..... 
     ) ii 
) i 
+0

嗯..你是什么意思'你不想要一个工会,你想要连接吗?'考虑到删除顶部1似乎工作..我怎样才能实现连接而不是联合? – Joe

+0

如果你将所有的行分开,那么不是所有行都加上一个独特的操作。联盟确实是一个明显的区别。 – usr

+0

好吧,而联盟所有不.. ..谢谢..它的工作原理! – Joe