我需要在Sql Server 2005中为select查询提供解决方案。
我想让一个查询返回两个ResultSet,每个ResultSet都保留了与某个条件匹配的所有记录的一半。我尝试将TOP 50 PERCENT与Order By结合使用但是如果表中的记录数是奇数,则两个结果集中都会显示一条记录。我不想在记录集上复制任何记录。例如:
我有一个带有TheID(PK)和TheValue字段(varchar(10))的简单表和5条记录。暂时跳过where子句。
SELECT TOP 50 PERCENT * FROM TheTable ORDER BY TheID asc
导致所选id为1,2,3
SELECT TOP 50 PERCENT * FROM TheTable ORDER BY TheID desc
导致所选ID为3,4,5
3是一个副本。在现实生活中,查询相当复杂,有大量where子句和子查询。
答案 0 :(得分:40)
SQL Server 2005及类似程序:
select *, ntile(2) over(order by theid) as tile_nr from thetable
ntile(n)
将输出分配到n个段中,每个段具有相同的大小(当行数不能被n整除时给予或舍入)。所以这会产生输出:
1 | value1 | 1
2 | value2 | 1
3 | value3 | 1
4 | value4 | 2
5 | value5 | 2
如果您只想要上半部分或下半部分,则需要将其放入子查询中,例如:
select theid, thevalue from (
select theid, thevalue, ntile(2) over(order by theid) as tile_nr from thetable
) x
where x.tile_nr = 1
将返回上半部分,同样使用x.tile_nr = 2
作为下半部分
答案 1 :(得分:7)
您可以使用以下两个查询:
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY TheID) AS rn FROM TheTable
) T1
WHERE rn % 2 = 0
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY TheID) AS rn FROM TheTable
) T1
WHERE rn % 2 = 1
答案 2 :(得分:2)
如果这是SQL Server 2000,那么我倾向于找到中间值的PK,如下所示:
Declare @MiddleId int
Set @MiddleId = (
Select TOP 1 PK
From (
Select TOP 50 PERCENT PK
From Table
Order By TheId ASC
)
Order By TheId DESC
)
Select ...
From Table
Where TheId <= @MiddleId
Select ..
From Table
Where TheId > @MiddleId
使用SQL Server 2005,我倾向于这样做但你可以使用CTE
;With NumProjects As
(
Select Id, ROW_NUMBER() OVER (ORDER BY TheId ASC ) As Num
From Table
)
Select @MiddleId = Id
From Table
Where Num = CEILING( (Select Count(*) From Table) / 2 )
答案 3 :(得分:1)
试试这个:
DECLARE @CountOf int,@Top int,@Bottom int
SELECT @CountOf=COUNT(*) FROM YourTable
SET @Top=@CountOf/2
SET @Bottom=@CountOf-@Top
SELECT TOP (@Top) * FROM YourTable ORDER BY 1 asc --assumes column 1 is your PK
SELECT TOP (@Bottom) * FROM YourTable ORDER BY 1 desc --assumes column 1 is your PK
答案 4 :(得分:0)
这是另一种解决方案:
您需要使用临时表来保存前50%,如下所示:
select top 50 percent *
into #YourTempTable
from TheTable
-- The below would give the first half
select * from #YourTempTable
-- The below woud give rest of the half
select * from TheTable where TheID not in (select TheID from #YourTempTable)
答案 5 :(得分:-1)
这是the query我发现有用(经过修改后):
DECLARE @numberofitemsperpage INT DECLARE @numberofpages INT DECLARE @currentpage int
DECLARE @countRecords float SET @countRecords =(选择COUNT(*)From sz_hold_visitsData) - Excel一次可以容纳大约一百万条记录。 if @countRecords&gt; = 1000000 SET @numberofitemsperpage = 500000 ELSE IF @countRecords&lt; 1000000 AND @countRecords&gt; = 500000 SET @numberofitemsperpage = 250000 ELSE IF @countRecords&lt; 500000 AND @countRecords&gt; = 100000 SET @numberofitemsperpage = 50000 ELSE SET @numberofitemsperpage = 10000
DECLARE @numberofpages_deci float SET @numberofpages_deci = @countRecords / @numberofitemsperpage
SET @numberofpages = CEILING(@numberofpages_deci)选择 @countRecords AS countRecords,@ numberofitemsperpage AS numberofitemsperpage,@ numberofpages_deci AS numberofpages_deci, @numberofpages AS numberofpagesFnl
SET @currentpage = 0 WHILE @currentpage&lt; @numberofpages BEGIN SELECT a。* FROM(SELECT row_number()OVER(ORDER BY person_ID)AS ROW,* FROM sz_hold_visitsData)一个WHERE ROW&gt; = @currentpage * @numberofitemsperpage +1 AND Row&lt; =(@ currentpage + 1)* @numberofitemsperpage
IF @@ ROWCOUNT = 0 BREAK SET @currentpage = @currentpage +1 END
在此摘录中,&#34; sz_hold_visitsData&#34;是我数据库中的一个表,而#34; person_ID&#34;是一个专栏。 您还可以进一步修改脚本以输出到文件:
希望有所帮助。DECLARE @numberofitemsperpage INT DECLARE @numberofpages INT DECLARE @currentpage int
DECLARE @countRecords float SET @countRecords =(选择COUNT(*)From sz_hold_visitsData) - Excel一次可以容纳大约一百万条记录。 if @countRecords&gt; = 1000000 SET @numberofitemsperpage = 500000 ELSE IF @countRecords&lt; 1000000 AND @countRecords&gt; = 500000 SET @numberofitemsperpage = 250000 ELSE IF @countRecords&lt; 500000 AND @countRecords&gt; = 100000 SET @numberofitemsperpage = 50000 ELSE SET @numberofitemsperpage = 10000
DECLARE @numberofpages_deci float SET @numberofpages_deci = @countRecords / @numberofitemsperpage
SET @numberofpages = CEILING(@numberofpages_deci)选择 @countRecords AS countRecords,@ numberofitemsperpage AS numberofitemsperpage,@ numberofpages_deci AS numberofpages_deci, @numberofpages AS numberofpagesFnl
DECLARE @sevrName nvarchar(50)SET @sevrName =&#39;。\ sql14&#39;宣布 @outputFile nvarchar(500)
SET @currentpage = 0 WHILE @currentpage&lt; @numberofpages BEGIN --SELECT a。* FROM(SELECT row_number()OVER(ORDER BY person_ID)AS ROW,* FROM sz_hold_visitsData)WHERE ROW&gt; = @currentpage * @numberofitemsperpage +1 AND Row&lt; =(@ currentpage + 1)* @numberofitemsperpage SET @outputFile =&#39; C:\ PSM \ outVisits _&#39; + convert(nvarchar(50),@ currentpage)+&#39; .csv&#39; - 选择@outputFile --TEST
DECLARE @cmd_ varchar(500)=&#39; sqlcmd -S&#39; + @sevrName +&#39; -E -Q &#34; SELECT a。* FROM(SELECT row_number()OVER(ORDER BY person_ID)AS ROW,* from sz_hold_visitsData)a WHERE ROW&gt; =&#39; + CONVERT(nvarchar(500),@ currentpage * @numberofitemsperpage +1)+&#39;和 行&lt; =&#39; + CONVERT(nvarchar(500),((@ currentpage + 1)* @numberofitemsperpage))+&#39;&#34; -s&#34;,&#34; -o&#39; + @ outputFile +&#39; &#39; - &#34; C:\ PSM \ outVisits.csv&#34; &#39; EXEC xp_cmdshell @cmd _
IF @@ ROWCOUNT = 0 BREAK SET @currentpage = @currentpage +1 END