2012-02-23 4 views
5

우리는 외부 회사에 데이터를 제공하라는 요청을 받았습니다. 데이터 샘플 만 필요합니다. 간단합니까? 잘못된. 여기 SQL 데이터 샘플링

는 샘플링 기준이다

    720 (요구되는 샘플 크기)로 나눈 레코드
  • 수 -이 결과는 일부 경우 샘플링 간격 (다음 전체 내림 준다 번호).

  • 샘플링 간격을 반으로 줄이면 시작점을 알 수 있습니다.

  • 샘플링 간격을 더하여 각 레코드를 반환하십시오.

예 :

  • 10,000 기록 - 샘플링 간격 = 13 (10000/720)
  • 출발점 = 6 (13/2 둥근)
  • 복귀 레코드 (6), 19 (6+ 13), 32 + 13 (19), 45 + 13 (32) 등 .....

누군가가 말해 줄 수주십시오 방법 (이 같은) 뭔가 SQL에서 가능합니다.

+0

어떤 브랜드의 SQL입니까? ROW_NUMBER()를 사용하면 많은 도움이됩니다. 또한 샘플링 간격이 720이고 정의 된 시작점 ***은 *** 데이터에 순서가 있음을 의미합니다. 따라서 데이터가 어떤 순서로 표시되어야합니까? – MatBailie

+0

ROW_NUMBER() OVER (TransactionDate로 주문) AS RowNumber, –

답변

2

ROW_NUMBER()를 사용하면 비교적 쉽게 처리 할 수 ​​있습니다.

SELECT 
    * 
FROM 
(
    SELECT 
    ROW_NUMBER() OVER (ORDER BY a, b, c, d) AS record_id, 
    * 
    FROM 
    yourTable 
) 
    AS data 
WHERE 
    (record_id + 360) % 720 = 0 

ROW_NUMBER()

는 모든 데이터를 순차적 식별자 (이 둘 틈이 고유해야하며 안됩니다 id 필드 중요하다)를 제공합니다. 또한 데이터를 원하는 순서를 (ORDER BY a, b, c, d)으로 정의합니다.

해당 ID를 사용하면 Modulo (종종 % 연산자)를 사용하면 720 번째 레코드, 1440 번째 레코드 등 (720 % 720 = 0이므로) 레코드인지 테스트 할 수 있습니다.

그런 다음 id 값을 360으로 오프셋하면 결과 집합의 시작점을 변경할 수 있습니다.

편집 질문을 다시 읽은 후

, 난 당신이 모든 720번째 기록을하지 않으려는 볼 수 있지만, 균일 (720 개) 기록을 선정했다. 이와 같이

, (SELECT COUNT(*)/720 FROM yourTable)

으로 720 대체 정확히 720 기록 결과를 허용 라운딩 조건을 무시 (SELECT (COUNT(*)/720)/2 FROM yourTable)

EDIT

으로 360 대체. 이를 위해서는 정수가 아닌 값을 사용해야하고 모듈로의 결과는 1보다 작아야합니다.

WHERE 
    (record_id + (SELECT COUNT(*) FROM yourTable)/1440.0) 
    % 
    ((SELECT COUNT(*) FROM yourTable)/720.0) 
    < 
    1.0 
+0

좋아요. 반환하기 위해 수집 한 데이터에 대한 내 쿼리를 실행합니다.이 쿼리는 9353 개의 레코드를 제공합니다. 샘플링 간격은 12, 시작 지점은 6이어야합니다. 내가 코드를 추가하면 779 개의 행이 반환됩니다. –

+0

@ 리차드 - 779 개의 행은 샘플 간격을 정수로 반올림해야하기 때문에 발생합니다. '9353/720 = 12.99' =>'12'. 그런 다음'9353/12 = 779.33' =>'779'입니다. 어떤 부분이 가장 중요한지 아십니까? 샘플 간격을 반올림하거나 정확하게 720 레코드를 반환합니까? *** [둘 다 가질 수는 없습니다.] *** – MatBailie

+0

데이터 요청에서 720을 대상으로합니다. –

1
declare @sample_size int, @starting_point int 

select @sample_size = 200 

select top (@sample_size) col1, col2, col3, col4 
from (
    select *, row_number() over (order by col1, col2) as row 
    from your_table 
) t 
where (row % ((select count(*) from your_table)/@sample_size)) - (select count(*) from your_table)/@sample_size/2) = 0 

SQL 서버 2005 +에서 작동하는 것입니다.

TOP (@variable)

는 수와 순서 행과 ROW_NUMBER() (때문에 더 그런 다음 필요한 행을 반환 할 수 있습니다, 충분하지 않을 수 있습니다 반올림 정수의 where 상태) 행을 제한하는 데 사용됩니다.

근무 예 : http://data.stackexchange.com/stackoverflow/query/62315/sql-data-sampling 코드 아래 : 당신은 행 번호를 얻기 위해 순위를 사용할 수

declare @tab table (id int identity(1,1), col1 varchar(3), col2 varchar(3)) 

declare @i int 

set @i = 0 

while @i <= 1000 
begin 
    insert into @tab 
    select 'aaa', 'bbb' 
    set @i = @i+1 
end 

declare @sample_size int 

select @sample_size = 123 

select ((select count(*) from @tab)/@sample_size) as sample_interval 

select top (@sample_size) * 
from (
    select *, row_number() over (order by col1, col2, id desc) as row 
    from @tab 
) t 
where (row % ((select count(*) from @tab)/@sample_size)) - ((select count(*) from @tab)/@sample_size/2) = 0 
+0

왜 "-1"이라고 설명 할 수 있습니까? 어쩌면 새로운 것을 배울 것입니다. –

+0

당신의 솔루션은 좋지만, I-1이 동적 접근법이 아니라는 이유가 있습니다. SP는 실제로 출발점 자체를 계산해야합니다. –

+0

@ 리차드, 오케이, 잘못 읽고 있지만 수정하고 수정하기 쉽습니다. –

-1

. 다음 코드는 테이블에 10000 개의 레코드를 만든 다음 총 769 개의 ​​행에 대해 6, 19, 32 번째 등을 선택합니다.

CREATE TABLE Tbl (
    Data varchar (255) 
) 
GO 

DECLARE @i int 
SET @i = 0 
WHILE (@i < 10000) 
BEGIN 
    INSERT INTO Tbl (Data) VALUES (CONVERT(varchar(255), NEWID())) 
    SET @i = @i + 1 
END 
GO 

DECLARE @interval int 
DECLARE @start int 
DECLARE @total int 
SELECT @total = COUNT(*), 
     @start = FLOOR(COUNT(*)/720)/2, 
     @interval = FLOOR(COUNT(*)/720) 
FROM Tbl 

PRINT 'Start record: ' + CAST(@start as varchar(10)) 
PRINT 'Interval: ' + CAST(@interval as varchar(10)) 

SELECT rank, Data 
FROM (
    SELECT rank() 
    OVER (ORDER BY t.Data) as rank, t.Data AS Data 
    FROM Tbl t) q 
WHERE ((rank + 1) + @start) % @interval = 0 
+0

왜 RANK()입니까? 레코드의 순위 값이 같으면 충돌이 발생하고 동일한 RANK()로 여러 값이 발생합니다. 이로 인해과 선택 (관심 대상 RANK()가있는 다중 값)과 과소 선택 (해당 순위로 인해 누락 순위가 실제로 다른 위치에서 연결됨)로 이어질 수 있습니다. ROW_NUMBER()를 사용 하시겠습니까? – MatBailie

0

SQL 서버에 내장 된 기능이 있습니다.
SELECT 성, 성 FROM Person.Person TABLESAMPLE (10 PERCENT);