문제

각 행을 얻으려면이 DB를 쿼리해야하지만 결과의 열 값 중 하나의 합도 필요합니다. PHP를 사용하여 총 값을 얻을 수 있었지만 총 2 개의 루프를 실행해야합니다. 하나는 총계를 얻습니다 (결과 위의 맨 위에 있습니다). 그래서 나는 쿼리가 그것을 잡고 "총"행을 만들기 위해 쿼리를 선호하지만, 내가 작동하는 유일한 방법은 본질적으로 원래 쿼리의 반복 인 하위 쿼리입니다. 더 좋은 방법이 있습니까?

SELECT 
CONCAT(u.firstname, ' ', u.lastname ) name, u.id, s.description, s.shiftstart, s.shiftend, 
    (SELECT 
    SUM( TIME_TO_SEC( TIMEDIFF( shiftend, shiftstart ) ) ) /3600
    FROM shifts
    WHERE id =  '$user'
    AND DATE( shiftstart )
    BETWEEN '$start'
    AND '$end') total
FROM shifts s
INNER JOIN users u ON ( s.id = u.id )
WHERE s.id = '$user'
AND DATE( shiftstart )
BETWEEN '$start'
AND '$end'
ORDER BY shiftstart

위의 작품 및 출력 :

name        id     description  shiftstart             shiftend               total
Joe User    joeuser    Stuff    2009-01-05 07:45:00    2009-01-05 12:15:00    39.5000
Joe User    joeuser    Stuff    2009-01-05 13:00:00    2009-01-05 17:00:00    39.5000
Joe User    joeuser    Stuff    2009-01-06 07:45:00    2009-01-06 10:45:00    39.5000
Joe User    joeuser    Stuff    2009-01-06 10:45:00    2009-01-06 12:45:00    39.5000
Joe User    joeuser    Stuff    2009-01-06 13:30:00    2009-01-06 14:30:00    39.5000
Joe User    joeuser    Stuff    2009-01-06 14:30:00    2009-01-06 17:00:00    39.5000
Joe User    joeuser    Stuff    2009-01-07 09:45:00    2009-01-07 14:00:00    39.5000
Joe User    joeuser    Stuff    2009-01-07 15:00:00    2009-01-07 17:00:00    39.5000
Joe User    joeuser    Stuff    2009-01-08 08:00:00    2009-01-08 12:15:00    39.5000
Joe User    joeuser    Stuff    2009-01-08 13:15:00    2009-01-08 17:00:00    39.5000
Joe User    joeuser    Stuff    2009-01-09 07:45:00    2009-01-09 10:45:00    39.5000
Joe User    joeuser    Stuff    2009-01-09 11:45:00    2009-01-09 15:15:00    39.5000
Joe User    joeuser    Stuff    2009-01-09 15:15:00    2009-01-09 17:00:00    39.5000

이것이 내가 필요한 것이지만 아마도 그것을 얻는 가장 좋은 방법은 아닙니다.

도움이 되었습니까?

해결책

MySQL은 호출 된 특수 그룹 별 수정자를 지원합니다 롤업.

SELECT CONCAT(u.firstname, ' ', u.lastname ) name, u.id, 
  s.description, s.shiftstart, s.shiftend, 
  SUM( TIME_TO_SEC( TIMEDIFF( shiftend, shiftstart ) ) ) /3600 total
FROM shifts s INNER JOIN users u ON ( s.id = u.id )
WHERE s.id = ? AND DATE( shiftstart ) BETWEEN ? AND ?
GROUP BY u.id, s.shiftstart WITH ROLLUP
ORDER BY shiftstart;

다른 팁

더 좋은 방법은 코드 로이 작업을 수행하는 것입니다. 사람들은 절차 적 의무를 수행하기 위해 관계형 대수 인 SQL을 계속 사용한다고 주장합니다. SQL에 대한 절차 적 신발을 구하려고하는 것은입니다 언제나 복잡성과 성능 측면에서 나쁜 생각. 전문 DBA 로부터이 조언을 받으십시오.

코드에서 두 쿼리를 실행하십시오. 더 큰 세트를 먼저 출력 한 다음 원하는 형식으로 총 라인을 출력하십시오. 쿼리는 더 작고 단순하며 성능이 향상되며 원하는 출력을 얻을 수 있습니다.

다른 조언 - 디스크 공간은 저렴하며 대부분의 데이터베이스 테이블은 작성된 것보다 훨씬 자주 읽습니다. 삽입/업데이트 트리거 (MySQL에서 가능한 경우)를 설정하여 계산 된 필드와 같은 별도의 열을 채우십시오.CONCAT(u.firstname,' ',u.lastname)"그리고 쿼리에 그것을 사용하십시오. 매당 함수는 확장 할 수 없으며 DBMS 성능이 커질수록 DBMS 성능을 제거합니다.

비교하면 무엇이든 더 나을 수 있습니다. 문제는 무엇과 비교하는 것입니다.

당신이 지시 한 주요 문제는 당신이 결과의 최상위에 총계를 원한다는 것입니다. Crystal Reports 및 기타 앱은 2 패스 엔진으로 이러한 종류의 마법을 관리합니다. 첫 번째 패스는 총계를 얻습니다.

모든 솔루션과 함께 트레이드 오프가 있습니다. 별도의 "총"행을 얻는 경우 수신 앱은 결과에서 벗어나거나 다른 트릭을 재생하여 숨겨야합니다.

1 백만 명이/HR 웹 사이트를 작성하지 않는 경우 옵션이 될 수있는 한 가지 가능성은 단순히 2 개의 전화를하는 것입니다. 세부 사항 ... 한 사람의 결과를 선택하는 쿼리에서 나타납니다.

우리는 오버 헤드와 대역폭을 저장하기위한 것이지만 때로는 단순합니다.

편집 : Pax는 "저장"버튼으로 나를 이겼습니다 ... LOL ...

Bill Karwin의 응답에 설명 된 대로이 목적을 위해 제공된 MySQL 확장자를 사용하십시오 (나는 나 자신을 확보했습니다).

이를 사용할 수없는 경우 옵션 2는 또 다른 SQL 문입니다. SELECT SUM ...) SQL은 실제로 작성할 절차 적 코드 루핑에 비해 이러한 종류에 대해 매우 효율적으로 최적화됩니다.

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