MySQL의 단일 쿼리에서 레코드를 계산하고 제한하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/802373

  •  03-07-2019
  •  | 
  •  

문제

다음과 같이 테이블의 레코드를 검색하고 있습니다.

SELECT Id, Name FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10;

이제 페이징을 유지하기 위해 한도를 추가하고 있습니다. 그러나 사용자가 'Prashant'라는 단어를 검색하면 'Prashant'의 경우 총 레코드가 124입니다. 그러나 쿼리에 제한이 적용되므로 PHP 스크립트에서 10 개의 레코드 만 가져오고 PHP 코드의 MySQL 변수를 계산할 때 전체 레코드를 반환하는 것은 10입니다.

따라서 기본적으로 위의 쿼리에서 약간의 수정을 통해 단일 쿼리를 사용하여 계산하고 제한하고 싶습니다. 레코드의 총 카운트 (124)를 원합니다. 쿼리에서 찾은 총 결과를 계산하기 위해 별도의 카운트 (*) 쿼리를 실행하고 싶지 않습니다.

감사.

도움이 되었습니까?

해결책

SELECT SQL_CALC_FOUND_ROWS
  Id, Name
FROM my_table
WHERE
  Name LIKE '%prashant%'
LIMIT 0, 10;

# Find total rows
SELECT FOUND_ROWS();

더 많은 정보

다른 팁

MySQL 은이 작업을 수행하는 것을 지원합니다 SQL_CALC_FOUND_ROWS Ionut가 언급했듯이. 그러나 그 결과가 밝혀졌습니다 많은 경우에 실제로 두 가지 진술을 사용하여 구식 방식으로하는 것이 더 빠릅니다. 그 중 하나는 규칙입니다. count(). 그러나 이것은 인덱스 스캔을 사용하여 계산을 수행 할 수 있어야합니다.이 쿼리의 경우에는 해당되지 않지만 어쨌든 언급 할 것이라고 생각했습니다.

이것은 같은 필요가있는 다른 사람들을위한 것입니다 (이 질문의시기부터 3 년이 지났다고 생각).

비슷한 문제가 있었고 2 개의 쿼리를 만들고 싶지 않았습니다. 그래서 내가 한 것은 총 숫자에 대한 추가 열을 만들고 LIMIT 그리고 OFFSET 결국 조항 :

SELECT SQL_CALC_FOUND_ROWS * FROM (
    SELECT `id`, `name`
    FROM `my_table`
    WHERE `name` LIKE '%prashant%'
) res,
(SELECT /*CEIL(FOUND_ROWS()/10) AS 'pages',*/ FOUND_ROWS() AS 'total') tot
LIMIT 0, 10

결과는 같은 것입니다

| id  |      name      | total |
+-----+----------------+-------+
|  1  | Jason Prashant |  124  |
|  2  | Bob Prashant   |  124  |
|  3  | Sam Prashant   |  124  |
|  4  | etc. prashant  |  124  |

그리고이 솔루션은 결과를 한 번만 가져온 다음 사용하기 때문에 타이밍에 단점이 없다고 생각합니다. 이미 계산되었습니다 추가 열에 대한 행 계수.

거대한 테이블이 있고 여러 필드를 선택하는 경우 (예제에서와 같이 ID가 아닌 이름이 아닌) 2 개의 쿼리를 사용하는 것이 좋습니다. Count (0)를 먼저 클로즈가있는 모든 사람들과 함께, 그 후 페이지 매김, 데이터 선택 등을 구축하는 것만으로 먼저 (0) 인기있는 전자 상거래 웹 사이트에서 실제로 더 빠르게 작동합니다.

SQL_CALC_FOUND_ROWS 및 FOND_ROWS ()를 사용하지 마십시오.

  1. 보고 된 버그가 있습니다
    여기: https://bugs.mysql.com/bug.php?id=18454
    그리고 여기: https://bugs.mysql.com/bug.php?id=19553

  2. 작은 테이블에서 벤치 마크는 다른 것들에 더 의존하고 있으며, 선택하는 결과 시간은 Count (0)와 거의 동일합니다. -SQL_CALC_FOUND_ROWS는 여전히 데이터베이스 최적화에 의해 제한 및 주문에 대한 제한을 제한합니다. 사용하지 마십시오 sql_calc_found_rows

  3. 큰 테이블에서 벤치 마크 차이는 카운트 (0)가 0.003 초가 걸릴 수있는 경우에도 SQL_CALC_FOUND_ROWS가 20 초가 걸릴 수 있습니다.

모든 메트릭스 수는 (0)은 우수한 선택입니다.

카운트 (0) 구문 :

(SELECT COUNT(0) FROM tableNames WHERE condition) AS alias
// alias is optional but needed if you need to use the result later

그래서 당신의 총 쿼리는 다음과 같습니다

(SELECT COUNT(0) FROM my_table WHERE name LIKE '%prashant%') AS countResults;

SELECT Id, Name FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10;

그런 다음 다른 곳에서 필요한 곳마다 Countresults에게 전화하십시오 ...

Count (0)를 사용하는 또 다른 장점은 여기와 동일한 테이블을 검색하는 데 사용할 수 있다는 것입니다. 그렇지 않으면 다른 테이블을 검색하는 데 사용할 수 있습니다 ...

예를 들어, 발견 된 각 사람이 각각 3, 2, 1, 5 개의 Diffenrent 작업이 있으면 ...

(SELECT COUNT(0) FROM my_jobs_table WHERE name = name_row_in_jobs_table) AS jobs

원본 내부에서 이렇게 선택하십시오

SELECT Id, Name (SELECT COUNT(0) FROM my_jobs_table WHERE name = name_row_in_jobs_table) AS jobs FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10;

당신에게 :

--------------------
| id | Name | jobs |
--------------------
| 1  | Alice| 3    |
--------------------
| 2  | John | 2    |
--------------------
| 3  | Bob  | 1    |
--------------------
| 4  | Jill | 5    |
--------------------

따라서 이름 [3] (예 : Bob)을 표시 할 때 Bob이 작업을 호출하여 1 개의 직업을 가지고 있음을 보여줄 수도 있습니다 [3].

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top