I need a solution for a select query in Sql Server 2005.
I\'d like to have a query returning two ResultSets each of which holding exactly half of all records matchin
If this is SQL Server 2000, then I'd be inclined to find the PK of the middle value like so:
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
With SQL Server 2005, I'd be inclined to do the same but you can use a 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 )
SQL Server 2005 and similar:
select *, ntile(2) over(order by theid) as tile_nr from thetable
ntile(n)
allocates the output into n segments, each of the same size (give or take rounding when the number of rows isn't divisible by n). So this produces the output:
1 | value1 | 1
2 | value2 | 1
3 | value3 | 1
4 | value4 | 2
5 | value5 | 2
If you just want the top or bottom half, you need to put this into a subquery, e.g.:
select theid, thevalue from (
select theid, thevalue, ntile(2) over(order by theid) as tile_nr from thetable
) x
where x.tile_nr = 1
will return the top half, and similarly use x.tile_nr = 2
for the bottom half
You could use these two queries:
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
This is the query I found useful (after modifications of-course):
DECLARE @numberofitemsperpage INT DECLARE @numberofpages INT DECLARE @currentpage int
DECLARE @countRecords float SET @countRecords = (Select COUNT(*) From sz_hold_visitsData) -- the Excel can hold approximately ONE MILLION records at a time. if @countRecords >= 1000000 SET @numberofitemsperpage = 500000 ELSE IF @countRecords < 1000000 AND @countRecords >= 500000 SET @numberofitemsperpage = 250000 ELSE IF @countRecords < 500000 AND @countRecords >= 100000 SET @numberofitemsperpage = 50000 ELSE SET @numberofitemsperpage = 10000
DECLARE @numberofpages_deci float SET @numberofpages_deci = @countRecords / @numberofitemsperpage
SET @numberofpages = CEILING(@numberofpages_deci) Select @countRecords AS countRecords, @numberofitemsperpage AS numberofitemsperpage , @numberofpages_deci AS numberofpages_deci, @numberofpages AS numberofpagesFnl
SET @currentpage =0 WHILE @currentpage < @numberofpages BEGIN SELECT a.* FROM (SELECT row_number() OVER (ORDER BY person_ID) AS ROW, * FROM sz_hold_visitsData) a WHERE ROW >= @currentpage * @numberofitemsperpage +1 AND Row <= (@currentpage+1) * @numberofitemsperpage
IF @@ROWCOUNT = 0 BREAK SET @currentpage = @currentpage +1 END
In this extract, "sz_hold_visitsData" is a table in my database, whilst "person_ID" is a column therein. You can also further modify the script to output to file:
DECLARE @numberofitemsperpage INT DECLARE @numberofpages INT DECLARE @currentpage int
DECLARE @countRecords float SET @countRecords = (Select COUNT(*) From sz_hold_visitsData) -- the Excel can hold approximately ONE MILLION records at a time. if @countRecords >= 1000000 SET @numberofitemsperpage = 500000 ELSE IF @countRecords < 1000000 AND @countRecords >= 500000 SET @numberofitemsperpage = 250000 ELSE IF @countRecords < 500000 AND @countRecords >= 100000 SET @numberofitemsperpage = 50000 ELSE SET @numberofitemsperpage = 10000
DECLARE @numberofpages_deci float SET @numberofpages_deci = @countRecords / @numberofitemsperpage
SET @numberofpages = CEILING(@numberofpages_deci) Select @countRecords AS countRecords, @numberofitemsperpage AS numberofitemsperpage , @numberofpages_deci AS numberofpages_deci, @numberofpages AS numberofpagesFnl
DECLARE @sevrName nvarchar(50) SET @sevrName = '.\sql14' DECLARE @outputFile nvarchar(500)
SET @currentpage =0 WHILE @currentpage < @numberofpages BEGIN --SELECT a.* FROM (SELECT row_number() OVER (ORDER BY person_ID) AS ROW, * FROM sz_hold_visitsData) a WHERE ROW >= @currentpage * @numberofitemsperpage +1 AND Row <= (@currentpage+1) * @numberofitemsperpage SET @outputFile = 'C:\PSM\outVisits_' +convert(nvarchar(50), @currentpage) + '.csv' --Select @outputFile --TEST
DECLARE @cmd_ varchar(500) = 'sqlcmd -S ' + @sevrName + ' -E -Q "SELECT a.* FROM (SELECT row_number() OVER (ORDER BY person_ID) AS ROW, * FROM sz_hold_visitsData) a WHERE ROW >= '+ CONVERT(nvarchar(500),@currentpage * @numberofitemsperpage +1) +' AND Row <= ' + CONVERT(nvarchar(500),((@currentpage+1) * @numberofitemsperpage)) +'" -s "," -o ' +@outputFile +' ' -- "C:\PSM\outVisits.csv" ' EXEC xp_cmdshell @cmd_
IF @@ROWCOUNT = 0 BREAK SET @currentpage = @currentpage +1 END
Hope helps.
try this:
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
Here is another solution:
You would need to use a temp table to hold the first 50% as below:
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)