如何在此SQL Server 2000查询中创建偏移量?

时间:2014-11-10 18:57:42

标签: sql sql-server sql-server-2000

我想做一个偏移:从0到10000记录,从10000到20000记录等等。如何修改此查询以添加偏移量?另外,如何改进此查询以提高性能?

SELECT
  CASE
    WHEN c.DataHoraUltimaAtualizacaoILR >= e.DataHoraUltimaAtualizacaoILR AND c.DataHoraUltimaAtualizacaoILR >= t.DataHoraUltimaAtualizacaoILR THEN c.DataHoraUltimaAtualizacaoILR
    WHEN e.DataHoraUltimaAtualizacaoILR >= c.DataHoraUltimaAtualizacaoILR AND e.DataHoraUltimaAtualizacaoILR >= t.DataHoraUltimaAtualizacaoILR THEN e.DataHoraUltimaAtualizacaoILR
    WHEN t.DataHoraUltimaAtualizacaoILR >= c.DataHoraUltimaAtualizacaoILR AND t.DataHoraUltimaAtualizacaoILR >= e.DataHoraUltimaAtualizacaoILR THEN t.DataHoraUltimaAtualizacaoILR
    ELSE c.DataHoraUltimaAtualizacaoILR
  END AS 'updated_at',
  p.Email,
  c.ID_Cliente,
  p.Nome, 
  p.DataHoraCadastro, 
  p.Sexo, 
  p.EstadoCivil, 
  p.DataNascimento, 
  getdate() as [today],
  datediff (yy,p.DataNascimento,getdate()) as 'Idade',
  datepart(month,p.DataNascimento) as 'MesAniversario',
  e.Bairro,
  e.Cidade, 
  e.UF, 
  c.CodLoja as codloja_cadastro,
  t.DDD,
  t.Numero
FROM
  PessoaFisica p
LEFT JOIN
  Cliente c ON (c.ID_Pessoa = p.ID_PessoaFisica)
LEFT JOIN 
  Loja l ON (CAST(l.CodLoja AS integer) = CAST(c.CodLoja AS integer))
LEFT JOIN
  PessoaEndereco pe ON (pe.ID_Pessoa = p.ID_PessoaFisica)
LEFT JOIN 
  Endereco e ON (e.ID_Endereco = pe.ID_Endereco)
LEFT JOIN 
  PessoaTelefone pt ON (pt.ID_Pessoa = p.ID_PessoaFisica)
LEFT JOIN 
  Telefone t ON (t.ID_Telefone = pt.ID_Telefone)
WHERE 
   p.Email IS NOT NULL 
   AND p.Email <> '' 
   --and p.Email = 'aline.salles@uol.com.br'
GROUP BY 
   p.Email, c.ID_Cliente, p.Nome, p.EstadoCivil, p.DataHoraCadastro, 
   c.CodLoja, p.Sexo, e.Bairro, p.DataNascimento, e.Cidade, e.UF, 
   t.DDD, t.Numero, c.DataHoraUltimaAtualizacaoILR, e.DataHoraUltimaAtualizacaoILR, 
   t.DataHoraUltimaAtualizacaoILR
ORDER BY 
   updated_at DESC

3 个答案:

答案 0 :(得分:1)

整体流程

如果您可以访问更现代的SQL Server版本,则可以设置一个进程,以便每天将原始数据复制到新数据库。这可能最初是源数据库的精确副本,仅用于暂存数据。然后使用存储过程或SSIS构建转换过程以获得高性能。该过程会将您的数据转换为您想要的最终状态,并将其加载到最终数据库中。

复制过程可能是复制,但如果您的登台数据库是SQL Server 2005或更高版本,那么您还可以构建一个简单的SSIS作业来执行复制。每天在计划任务(SQL代理)中运行该作业。您可以组合两个 - 加载数据,然后转换 - 但是如果使用SSIS,那么我建议将它们保存为单独的SSIS包,这将有助于调试问题。在计划任务中,您可以背靠背运行这两个包。


<强>性能

您需要对表进行良好的索引,但仅靠索引是不够的。将CodLoja转换为整数将阻止您在该字段上使用索引。如果由于其他原因需要将它们存储为字符串,请考虑添加计算列

ALTER TABLE xyz Add CodLojaAsInt as (CAST(CodLoja as int))

然后在新计算列上放置一个索引。问题是ON或WHERE子句中的任何函数调用都会导致SQL Server扫描整个行并转换每一行,而不是峰值到索引。

答案 1 :(得分:0)

在搜索并再次查看我的问题后,@ fuqua帮助我解决了这个问题。基本上我会在我的本地数据库中创建一些更有组织的表,并从远程数据库中获取所有抽象/丑陋的数据,并将其本地处理到新表。

我将使用Elasticsearch来加速索引和查询。

答案 2 :(得分:0)

听起来您正试图模仿MySQL的SELECT ... LIMIT X,Y功能。 SQL Server没有这个。在SQL Server 2005+中,您可以在子查询中使用ROW_NUMBER()。但是,自2000年以来,你将不得不采取一种艰难的方式。

他们总是这样做,就像这样:

SELECT ... FROM Table WHERE PK IN 
    (SELECT TOP @PageSize PK FROM Table WHERE PK NOT IN
        (SELECT TOP @StartRow PK FROM Table ORDER BY SortColumn)
    ORDER BY SortColumn)
ORDER BY SortColumn

虽然我建议您重写它以使用EXISTS代替IN,并查看哪种方法更有效。如果您有复合主键,则必须使用EXISTS

That code and the other solutions are here