【问题标题】:SQL Count query. Even numbers odd numbersSQL 计数查询。偶数奇数
【发布时间】:2011-08-30 19:12:54
【问题描述】:

我有一个产品表,我需要知道表中的记录数。目标是将返回查询分为 2 个单独的查询。

If (Count(*) % 2) = 0 return top(Count(*) / 2)
else return top((Count(*) / 2) + 1)

主要查询是:

select coalesce(Price, ProductPrice) as Price, Product.ProductName, Customer.CustomerName, Product.CatalogNum from Product 
        inner join Customer on CustomerID = @custId
        left outer join CustomerPrice on dbo.Customer.CustomerID = dbo.CustomerPrice.CustomerID 
        and dbo.Product.ProductID = dbo.CustomerPrice.ProductID
        Where Product.ProductActive = 1 Order by Product.CatalogNum

【问题讨论】:

  • 如果只需要表中的记录数,可以SELECT COUNT(*) FROM productTable。但我不认为我理解你的问题......
  • 因此,如果行数为偶数,则需要表的上半部分,如果行数为奇数,则上半部分(向下舍入)加一行;是对的吗?哪个版本的 SQL Server?
  • Daniel Renshaw - 正是我的需要。 SQL Server Express 2008 r2
  • 中选择 count(*) ?
  • 所有反对票是怎么回事?一个好的问题。

标签: sql sql-server tsql sql-server-2008-r2 sql-server-2008r2-express


【解决方案1】:
DECLARE @Count int
SELECT @Count = COUNT(*) FROM SomeTable
SET @Count = CASE WHEN @Count % 2 = 0 THEN @Count / 2 ELSE @Count / 2 + 1 END
SELECT TOP(@Count) * FROM SomeTable ORDER BY SomeColumn

请注意,这里存在并发问题 - 行数可能会在第一个和第二个 select 语句之间发生变化,除非您应用适当的限制性锁定提示/事务隔离级别。

另请注意,ORDER BY 对于赋予“上半部分”任何含义至关重要。

For information on the TOP clause.

要获得下半部分,请执行相同操作,但如果是奇数则减去一个,并将排序顺序颠倒几次。

DECLARE @Count int
SELECT @Count = COUNT(*) FROM SomeTable
SET @Count = CASE WHEN @Count % 2 = 0 THEN @Count / 2 ELSE @Count / 2 - 1 END
SELECT * FROM (
    SELECT TOP(@Count) * FROM SomeTable ORDER BY SomeColumn DESC) AS Data
ORDER BY SomeColumn

【讨论】:

  • 我不需要担心并发。
  • 这很好用。下半场产品怎么拿到??
  • 谢谢。出于某种原因,我无法使用您提供的示例对后半部分进行排序。查询管理器写道: Msg 156, Level 15, State 1, Line 6 关键字“订单”附近的语法不正确。所以我对报告中的查询进行了排序。一切都很好。再次 10 倍
【解决方案2】:

可能不是最佳解决方案,但这可能对您有用:

DECLARE @Rows INT
SELECT @Rows = CASE WHEN COUNT(*) % 2 = 0 THEN COUNT(*)/ 2 ELSE COUNT(*) / 2 + 1 END FROM Table1
SET ROWCOUNT @Rows
SELECT * FROM Table1 
SET ROWCOUNT 0

【讨论】:

  • ROWCOUNT 确定要获取的记录数还是只告诉您获取了多少?
  • SET ROWCOUNT 限制返回的行数,而@@ROWCOUNT 告诉您返回了多少。
【解决方案3】:
DECLARE @a FLOAT
SET @a = (SELECT CEILING(COUNT(*)/2.0) FROM users)

SELECT TOP (CAST(@a AS INT)) * FROM users

【讨论】:

  • SQL 2008 是否允许您像这样为 TOP 使用变量?我知道 SQL 2005 不允许这样做。如果是这样,那个方法比我的答案要好得多。
  • 我是2005年测试的,需要括号内。
【解决方案4】:

试试:

 Select * From Table t
 Where (Select Count(*) From Table
        Where pkCol < t.PkCol) <=
       (Select Count(*)+1 From Table)/2

整数除法应该处理你正在用模运算符做的事情......

为了解决下面评论的不理解,如果表有偶数条记录,比如20条,那么count(*) = 20Count(*) + 1 = 21(Count(*)+1) / 2 = 10,查询将返回计数所在的所有记录pk 小于其 pk 的记录的数量小于或等于 10,即一半的记录。

如果有奇数条记录,比如 21 条,那么 count(*) = 21Count(*) + 1 = 22(Count(*)+1) / 2 = 11。查询将返回 pk 小于其 pk 的记录数小于或等于 11 的所有记录,即一半的记录加 1,与使用模运算符所做的相同。

【讨论】:

  • 整数除法在这里帮不了你,我一般不明白你的答案。
  • @MK,如果你不懂整数除法,那么 .... 2 / 2 = 1; 3/2 = 1; 4/2 = 2; 5/2 = 2;
  • 啊,我还是不明白你的答案,但现在除法部分有意义了。
猜你喜欢
  • 2016-04-21
  • 2020-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多