【问题标题】:Translate query from SQL Server to Access 2000将查询从 SQL Server 转换为 Access 2000
【发布时间】:2015-08-08 18:08:30
【问题描述】:

我有一个 Access 2000 .mdb 文件。我在同一个数据库中有这个查询,但在 SQL Server 上。该查询在 SQL Server 中运行良好,但在 Access 中出现错误;我想这是由于ROW_NUMBER()

我无法使用 vba 进行此查询,因为我必须使用 Odbc 驱动程序运行它。

SELECT *
FROM 
    (SELECT 
         *, 
         ROW_NUMBER() OVER (ORDER BY cognome,nome ASC) AS RowID
     FROM 
         (SELECT DISTINCT 
              (a.ID_PAZIENTE) AS codice,
              a.NOME AS nome,
              a.COGNOME AS cognome,
              a.TITOLO AS titolo,
              a.TELEFONOABITAZIONE AS tel,
              a.TELEFONOUFFICIO AS uff,
              a.FAX AS cell,
              a.E_MAIL AS email,
              a.SESSO AS sesso
          FROM 
              PAZIENTI AS a
          WHERE 1 = 1) AS AnagraficheDistinct
    ) AS Anagrafiche
WHERE 
    RowID >= 1 AND RowID <= 25
ORDER BY 
    cognome, nome ASC;

这是错误:

查询表达式中的语法错误(缺少运算符):“ROW_NUMBER() OVER (ORDER BY cognome,nome ASC)

我尝试按照在线文档转换查询,这就是我所做的:

SELECT *
    FROM (
  SELECT Top 10
  *
  FROM
  (
   SELECT DISTINCT TOP 20 p.ID_PAZIENTE,p.cognome,p.nome
   FROM PAZIENTI p   
   ORDER BY p.cognome ASC,p.nome ASC
   ) AS sub1
   ORDER BY sub1.cognome DESC,sub1.nome DESC
   ) AS anagrafiche
   ORDER BY  p.cognome ASC,p.nome ASC

不幸的是,这个查询返回了奇怪的结果。更改起始索引 (How do I implement pagination in SQL for MS Access?),有时会返回 10 个结果(页面大小),有时会返回 12 个基于起始索引(startpos + 页面大小)的结果。

我做错了什么或者这件事在没有 VBA 的情况下使用 Access 是不可能的?

谢谢

【问题讨论】:

    标签: sql-server ms-access ms-access-2010


    【解决方案1】:

    考虑以下问题。 RowNumber() 在 Access SQL 中不可用,但可以使用子查询按名称复制排名:

    SELECT * 
    FROM 
      (SELECT DISTINCT 
                 a.ID_PAZIENTE AS codice, 
                 a.NOME AS nome, 
                 a.COGNOME AS cognome, 
                 a.TITOLO AS titolo, 
                 a.TELEFONOABITAZIONE AS tel, 
                 a.TELEFONOUFFICIO AS uff, 
                 a.FAX AS cell, 
                 a.E_MAIL AS email, 
                 a.SESSO AS sesso,
                 (SELECT count(*)
                  FROM PAZIENTI As b
                  WHERE b.cognome <= a.cognome 
                    AND b.nome <= a.nome) As RowID
       FROM PAZIENTI AS a) AS AnagraficheDistinct 
       ) AS Anagrafiche 
    WHERE RowID >= 1 AND RowID <= 25 
    ORDER BY cognome, nome;
    

    【讨论】:

      【解决方案2】:

      首先,MS-Access中的Query在逻辑上与SQL-Server-Query完全不同。

      第一个为您提供按cognome,nome 排序的前 25 行。 Access-Query 以指定的顺序为您提供前 20 行中的最后 10 行。

      在 Access 中没有 ROW_NUMBER 等内置函数。并且因为您使用两个字段作为 ROW_NUMBER(认知、名称)的排序标准,所以使用 Count(*) 子查询不起作用。

      但我在 Access 中构建了一种 RANK-Function,也许这适合你。但是,如果cognome 中具有相同值的行数大于页面大小,它也可能会返回更多行,因为您为一个页面大小指定。在此查询中,重要的是只有 cognome 是 Count(*) 子查询的一部分。

      SELECT p.*
      FROM
      (
        SELECT codice, cognome, nome, titolo, tel, uff, cell, email
        FROM
        (
          SELECT DISTINCT a.ID_PAZIENTE AS codice, a.COGNOME AS cognome, 
                          a.NOME AS nome, a.TITOLO AS titolo, 
                          a.TELEFONOABITAZIONE AS tel, a.TELEFONOUFFICIO AS uff,  
                          a.FAX AS cell, a.E_MAIL AS email, a.SESSO AS sesso, 
                          (SELECT Count(*) FROM PAZIENTI AS temp 
                           WHERE temp.cognome < a.cognome
                          ) + 1 AS Rank
          FROM PAZIENTI AS a
        ) AS psub
      WHERE Rank >= 1 AND Rank <= 5
      ORDER BY Rank
      ) p
      ORDER BY cognome, nome
      

      如果这对您没有帮助,我认为您将需要一个 VBA 函数。但在这里,在每次查询之前重置计数器是至关重要的。

      另一个选项是使用 Pass-Through-Query 并将第一个查询直接发送到 SQL-Server。您必须在 Access 的 Query-Object 中指定 odbc-Connectionstring。

      【讨论】:

      • 好答案!只需在外部派生表中添加 Rank 即可在外部表的WHERE 中使用。您甚至可以删除外部表 p,因为不再需要它,因为 RowID 是在最里面的子查询中计算的。让我们看看 OP 是怎么想的。
      • 谢谢冻糕。我认为当有不止一行具有相同的 cognome 值时,需要使用单独的 ORDER BY 的外部查询。在这种情况下,排名值将是相同的,并且没有特定的顺序,除非我指定明确的 ORDER BY 作为最后一步
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-06
      • 1970-01-01
      • 2015-08-27
      • 1970-01-01
      • 2015-10-18
      • 1970-01-01
      相关资源
      最近更新 更多