문제
특정 번호에 도달 할 때까지 쿼리 및 레코드를 표시하는 방법은 무엇입니까?
학생의 돈의 총 합계가 1000에 도달 할 때까지 학생을 선택 하시겠습니까?
덧셈
Student ID Student Name Student Money
--------- ----------- --------------
1 John 190
2 Jenny 290
3 Ben 200
4 Andy 120
5 Lynna 300
500에서 멈추고 싶다면 레코드 번호 1과 2 (190 + 290)를 얻을 수 있습니다. 내가 1000에 멈추고 싶다면, 나는 4까지 레코드 1을 얻을 것이다.
해결책
SQL 테이블에는 "내재적"순서가 없으므로, 어떤 의미에서도 표현할 때까지 그에게 제공하기 위해 주문별로 주문을 지정해야합니다. ``첫 번째 ''레코드의 합은 XXX Limit N의 학생 주문에서 선택 합계 (돈)로 얻을 수 있습니다. 정수가 자연스럽게있는 보조 테이블 int를 사용하면 최대 적합한 것을 찾을 수 있습니다. n :
SELECT MAX(N) FROM INTS
WHERE (SELECT SUM(money) FROM student ORDER BY xxx LIMIT N) < 1000
마지막으로 전체 선택에서 한계 절을 위해 다른 중첩 선택으로 삽입하십시오. 그러나이 모든 냄새는 비효율적 일 것입니다! 중첩 된 선택이 너무 많고 너무 느리게 보일 때 자주 대안은 다음과 같은 단계 에서이 작업을 수행합니다. 먼저 "점진적 합"으로 임시 테이블을 구축 한 다음이를 사용하여 필요한 한도를 찾는 데 도움이됩니다.
다른 팁
내 답을 찾는 동안이 질문을 발견했습니다. 나는 동일한 작업을 수행하는 또 다른 방법이므로 더 효율적일 수 있기 때문에 솔루션을 여기에 두겠다고 생각했습니다. 트릭은 자체 조인 사용입니다 >=
SELECT s1.ID, s1.name, s1.money, sum(s2.money)
FROM student s1
INNER JOIN student s2 ON s1.id >= s2.id
GROUP BY s1.id HAVING SUM(s2.money) <= 500;
죄송합니다 ... MySQL ...이 솔루션은 MS SQL을위한 것입니다 ...
다음은 row_number () 함수를 사용하는 솔루션입니다.
SELECT Student.*, SUM(StudentBefore.Money) AS AccumulatedMoney
FROM (
SELECT *, ROW_NUMBER() OVER(ORDER BY Id) AS RowNumber
FROM Students
) AS Student
INNER JOIN
(
SELECT *, ROW_NUMBER() OVER(ORDER BY Id) AS RowNumber
FROM Students
) AS StudentBefore
ON StudentBefore.RowNumber <= Student.RowNumber
GROUP BY Student.RowNumber, Student.Id, Student.Name, Student.Money
HAVING SUM(StudentBefore.Money) < 1000
실행 계획은 테이블을 정렬하는 것이 가장 비싼 작업임을 나타냅니다. 열에 정렬 할 인덱스가있는 경우 - 예제는 기본 키 ID로 정렬하려는 것을 나타냅니다. 인덱스 스캔이 가장 비싼 작업이됩니다.