2011-03-01 67 views
4

问题是我们要获得给定行之前和之后的行总数(由主键标识)。SQL:给定行之前和之后的行

我在T-SQL(MSSQL 2008)中尝试了以下内容。它给出了正确的结果,但我不知道这是否是最好的办法。

;WITH cte_before AS 
(
    SELECT ROW_NUMBER() OVER (Order By CustomerId) [Row Number], customerid, 
      firstName 
    FROM SalesLT.Customer 
), 
cte_nums AS 
(
    SELECT ROW_NUMBER() OVER (Order By CustomerId) [Row Number1] 
    FROM SalesLT.Customer 
) 
SELECT [Row Number]-1 [before], MAX([Row Number1]) - [Row Number] 
     , CustomerID, FirstName 
FROM cte_nums, cte_before 
GROUP BY [Row Number], CustomerID, FirstName 
HAVING CustomerID = 55 

我们怎样才能提高它在T-SQL和我们如何能够在其他SQL方言和服务器(如Oracle,MySQL和SQLite的,火鸟等)

+0

由于'[quote]字符的非标准用法,该语句将永远不会与任何其他DBMS一起运行。如果您避免需要引用或使用标准'“字符的列名,上述语句将在Oracle,PostgreSQL,DB2(以及即将推出的Firebird 3.0,因为它也支持窗口函数)运行 – 2011-03-01 20:30:12

+0

是@a_horse_with_no_name(它将会更好,如果你得到一个名字)这只是为了t-sql – TheVillageIdiot 2011-03-02 03:45:39

回答

2

我认为这会在任何方言的工作:

select 
    (select count(*) from SalesLT.Customer where customerid < 55) as rows_before, 
    (select count(*) from SalesLT.Customer where customerid > 55) as rows_after, 
    CustomerID, FirstName 
from SalesLT.Customer 
where CustomerID = 55 
0

一种改进版本的SQL完成:

DECLARE @CustomerId int 

SET @CustomerId = 55 

SELECT 
    @CustomerId 
    ,ThisOne.FirstName 
    ,sum(case when Agg.CustomerId < @CustomerId then 1 else 0 end) [Before] 
    ,sum(case when Agg.CustomerId > @CustomerId then 1 else 0 end) [After] 
from SalesLT.Customer Agg 
    inner join SalesLT.Customer ThisOne 
    on ThisOne.CustomerId = @CustomerId 
+0

你错过了'group by'这个自加入的目的是什么 – 2011-03-01 19:21:38

+0

这甚至没有执行 – TheVillageIdiot 2011-03-01 19:32:46

+0

这个连接是为了检索指定的CustomerId的FirstName(因为它是原始结果集的一部分)。至于执行与否,错误信息是什么?我做了一个数据集,没有可以测试代码的语法错误。 – 2011-03-01 19:55:36

1

相同的思路菲利普的,但实施适当的并经过测试。这仅使用股票标准ANSI SQL。

SELECT A.customerid, A.firstName, 
    count(case when B.customerid < A.customerid then 1 end) count_before, 
    count(case when B.customerid > A.customerid then 1 end) count_after 
FROM SalesLT.Customer A 
cross join SalesLT.Customer B 
where A.customerID=55 
GROUP BY A.customerid, A.firstName 

“A”别名找到您想要的客户(55)。与B的连接为每个客户产生一行,为每一行测试A.customerID。

的情况下产生子句

  • 1;当条件< A.customerid [55]被满足
  • 空(隐式无ELSE子句)时未满足
  • Count跳过空值,所以总出来权利要求

GROUP BY使用COUNT(),一个聚合函数

相关问题