web-dev-qa-db-ja.com

選択クエリの結果を2つの等しい半分に分割する方法はありますか?

SQL Server 2005の選択クエリのソリューションが必要です。

特定の基準に一致するすべてのレコードのちょうど半分を保持する2つのResultSetを返すクエリが必要です。 Order Byと組み合わせてTOP 50 PERCENTを使用してみましたが、テーブルのレコード数が奇数の場合、1つのレコードが両方の結果セットに表示されます。レコードセットに重複するレコードを作成したくありません。例:

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句とサブクエリがあります。

17
Mats

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_を使用します

43
araqnid

次の2つのクエリを使用できます。

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
7
Mark Byers

これが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 )
2
Thomas

これを試して:

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
1
KM.

ここに別の解決策があります:

次のように、最初の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)
0
Unbound