다음 MySQL 테이블을 사용합니다.
+-----------------------------+
+ id INT UNSIGNED +
+ name VARCHAR(100) +
+-----------------------------+
으로 정렬 할 때 단일 행과 테이블의 다른 행 사이에서 위치를 선택하려면 어떻게해야합니까 name ASC
? 따라서 테이블 데이터가 다음과 같으면 이름별로 정렬 할 때 :
+-----------------------------+
+ id | name +
+-----------------------------+
+ 5 | Alpha +
+ 7 | Beta +
+ 3 | Delta +
+ ..... +
+ 1 | Zed +
+-----------------------------+
해당 Beta
행의 현재 위치를 가져 오는 행을 어떻게 선택할 수 있습니까? 내가 찾고있는 결과 세트는 다음과 같습니다.
+-----------------------------+
+ id | position | name +
+-----------------------------+
+ 7 | 2 | Beta +
+-----------------------------+
간단한 작업을 수행 한 SELECT * FROM tbl ORDER BY name ASC
다음 PHP에서 행을 열거 할 수 있지만 단일 행에 대해 잠재적으로 큰 결과 집합을로드하는 것은 낭비 인 것 같습니다.
답변
이것을 사용하십시오 :
SELECT x.id,
x.position,
x.name
FROM (SELECT t.id,
t.name,
@rownum := @rownum + 1 AS position
FROM TABLE t
JOIN (SELECT @rownum := 0) r
ORDER BY t.name) x
WHERE x.name = 'Beta'
… 고유 한 위치 값을 얻습니다. 이:
SELECT t.id,
(SELECT COUNT(*)
FROM TABLE x
WHERE x.name <= t.name) AS position,
t.name
FROM TABLE t
WHERE t.name = 'Beta'
… 동점에 동일한 가치를 부여합니다. IE : 두 번째 위치에 두 개의 값이있는 경우 첫 번째 쿼리가 둘 중 하나에 2의 위치를, 다른 하나에 3의 위치를 제공 할 때 둘 다 위치가 2가됩니다.
답변
이것이 제가 생각할 수있는 유일한 방법입니다.
SELECT `id`,
(SELECT COUNT(*) FROM `table` WHERE `name` <= 'Beta') AS `position`,
`name`
FROM `table`
WHERE `name` = 'Beta'
답변
쿼리가 단순하고 반환 된 결과 집합의 크기가 잠재적으로 큰 경우이를 두 개의 쿼리로 분할 할 수 있습니다.
축소 필터링 기준이있는 첫 번째 쿼리는 해당 행의 데이터 만 검색하고 두 번째 쿼리는 COUNT
with WHERE
절을 사용하여 위치를 계산합니다.
예를 들어 귀하의 경우
쿼리 1 :
SELECT * FROM tbl WHERE name = 'Beta'
쿼리 2 :
SELECT COUNT(1) FROM tbl WHERE name >= 'Beta'
2M 레코드가있는 테이블에서이 접근 방식을 사용하며 이는 OMG Ponies의 접근 방식보다 확장 성이 훨씬 뛰어납니다.
답변
다른 답변은 너무 복잡해 보입니다.
다음은 간단한 예 입니다. 열이있는 테이블이 있다고 가정 해 보겠습니다.
userid | points
사용자 ID를 포인트별로 정렬하고 행 위치 (사용자의 “순위”)를 얻으려면 다음을 사용합니다.
SET @row_number = 0;
SELECT
(@row_number:=@row_number + 1) AS num, userid, points
FROM
ourtable
ORDER BY points DESC
num
행 위치 (순위)를 제공합니다.
MySQL 8.0 이상이있는 경우 ROW_NUMBER () 를 사용하는 것이 좋습니다.
답변
테이블에서 행의 위치는 대상 행보다 “더 나은”행 수를 나타냅니다.
따라서 해당 행을 계산해야합니다.
SELECT COUNT (*) + 1 from table
WHERE name
< ‘베타’
동점 일 경우 가장 높은 순위가 반환됩니다.
기존 “Beta”행 뒤에 “Beta”라는 이름이 같은 다른 행을 추가하면 분류에서 동일한 위치를 공유하므로 반환 된 위치는 여전히 2입니다.
질문 소유자가 이미 문제를 해결했다고 생각하므로 향후 유사한 것을 검색하는 사람들에게 도움이되기를 바랍니다.
답변
저에게는 매우 유사한 문제가 있으므로 동일한 질문을하지 않겠습니다.하지만 여기서 제가 한 일을 공유하고 AVG에서 그룹 별 및 주문을 사용해야했습니다. 서명과 소 코어가있는 학생이 있는데 순위를 매겨 야했습니다 (즉, 먼저 AVG를 계산 한 다음 DESC에서 주문한 다음 마지막으로 순위를 추가해야하므로 뭔가 매우 유사 은 AS 가장 좋은 대답 ) 내 문제에 적응 약간의 변화가 여기 :
마지막으로 position
외부 SELECT에 (순위) 열을 넣었습니다.
SET @rank=0;
SELECT @rank := @rank + 1 AS ranking, t.avg, t.name
FROM(SELECT avg(students_signatures.score) as avg, students.name as name
FROM alumnos_materia
JOIN (SELECT @rownum := 0) r
left JOIN students ON students.id=students_signatures.id_student
GROUP BY students.name order by avg DESC) t
답변
나는 받아 들여진 대답을 살펴 보았고 약간 복잡해 보였으므로 여기에 단순화 된 버전이 있습니다.
SELECT t,COUNT(*) AS position FROM t
WHERE name <= 'search string' ORDER BY name