"중첩 쿼리"가 필요한 이유는 무엇입니까? 우리는 관계형 대수가 아닌 SQL의 사고 방식에서 생각하고있는 "중첩 쿼리"를 사용할 필요가 없습니다. 관계 대수로 우리가 관계를 도출하고 다른 입력으로 한 관계의 출력을 사용하므로 다음과 같은 사실이 개최 것 : 우리가 절대적으로 필요하지 않는 한 arel 할 수있는 이름 바꾸기를 떠날 경우
points = Table(:points, {:as => 'sorted'}) # rename in the options hash
final_points = points.order('timestamp DESC').group(:client_id, :timestamp).project(:client_id, :timestamp)
그것은 좋습니다.
여기에서 관계 (예 : 정렬. *)에서 모든 도메인을 투영 할 수 없기 때문에 client_id와 timestamp의 투영은 매우 중요합니다. 관계에 대해 그룹화 작업 내에서 사용될 모든 도메인을 구체적으로 투영해야합니다. 그 이유는 그룹화 된 client_id를 뚜렷하게 대표 할 * 값이 없다는 것입니다. 예를 들어
을 값이 27 또는 69 수 중 하나 때문에 그룹이 점수 도메인에 프로젝션을 수행 할 수 없습니다하지만 당신은 합 (점수를) 프로젝트 수 있다면 당신은
client_id | score
----------------------
4 | 27
3 | 35
2 | 22
4 | 69
여기에 다음과 같은 테이블이 있다고 가정 해
그룹에 고유 한 값을 가진 도메인 속성 만 프로젝션 할 수 있습니다 (일반적으로 sum, max, min과 같은 집계 함수). 귀하의 질의를 통해 포인트가 타임 스탬프별로 정렬되었는지는 중요하지 않습니다. 왜냐하면 결국에는 client_id로 그룹화 될 것이기 때문입니다. 그룹화를 나타낼 수있는 단일 타임 스탬프가 없기 때문에 타임 스탬프 순서는 관련이 없습니다.
내가 Arel을 어떻게 도울 수 있는지 알려주십시오. 또한 저는 Arel을 핵심으로 사용하는 사람들을위한 학습 시리즈를 진행해 왔습니다. 시리즈 중 첫 번째는 http://Innovative-Studios.com/#pilot입니다. ActiveRecord 모델 포인트가 아닌 테이블 (: 점)을 사용한 이후로 어떻게 시작했는지 알 수 있습니다.
자세한 답변을 보내 주셔서 감사합니다. "그룹화를 나타낼 수있는 단일 타임 스탬프가 없으므로 타임 스탬프 순서가 적절하지 않습니다." 네가 옳아; 나는 네가하는 말을 본다. MySQL은 client_id 그룹의 첫 번째 행만 반환함으로써이 불일치를 해결합니다. 나는 이것이 내가 의지해야 할 행동이 아니라는 것을 알았다. 목표는 모든 client_ids에 대한 가장 최근의 지점, 즉 각 client_id 그룹별로 최대 타임 스탬프가있는 단일 지점을 반환하는 것입니다. 자주 폴링되기 때문에 하나의 쿼리에서 수행하는 것이 중요합니다. – Schrockwell
일부 집계 함수를 사용해야합니다. 우리가 "우리가 무엇을하려 하는가?"라고 물으면 대답은 SQL에서 max (timestamp)를 전달할 수 있도록 가장 최근 또는 최대 날짜를 찾는 것입니다. 이것은 Arel :: Attribute :: Expression :: Maximum에 해당하며 정렬 된 [: timestamp] .maximum()과 같이 Arel :: Attribute에서 구문 설탕으로 호출 할 수 있습니다. 하나의주의 사항이 있습니다. 그룹 작업 #group ('client_id, timestamp')에 타임 스탬프를 추가했는지 확인하십시오. 그렇지 않으면 전체 그룹화 시나리오에 오류가 발생합니다. 나는 MAX 집계 함수가 Postgres의 날짜에서 작동한다는 것을 알고 있으며, MySQL에서도 그렇다고 확신한다. – Snuggs
첫째, 정렬 및 순서는 관계형 대수의 일부가 아닙니다. Arel은 그것을 어쨌든 정의합니다. 두 번째로, 서브 쿼리가 관계형 대수의 일부인지 아닌지는 부적합합니다. 개념적으로 SELECT의 결과는 WHERE 절이 실행될 때까지 표시되지 않습니다. 따라서 모든 데이터베이스 (예 : Postgres)가 WHERE 절에서 열 별칭을 허용하지 않고 대신 하위 쿼리를 사용합니다. Arel이 하위 쿼리를 처리 할 수없는 경우 WHERE 절의 이름에 별칭을 지정할 수 없습니다. Arel에 의존하여 이름을 생성 할 수 없으면 지저분해질 수 있습니다. –