2012-08-04 2 views
0

1.11 모델에 가입 :방법 선택에 매우 긴 MySQL의 쿼리를 번역하고 젠드 프레임 워크 나는이 MySQL의 쿼리가

SELECT 
    freeAnswers.*, 
    (SELECT `districtCode` 
     FROM `geodatas` 
     WHERE `zipCode` = clients.zipCode 
     GROUP BY `zipCode` 
     LIMIT 0, 1) as districtCode, 
    clients.zipCode, 
    clients.gender, 
    clients.startAge, 
    clients.endAge, 
    clients.mail, 
    clients.facebook, 
    surveys.customerId, 
    surveys.activityId, 
    surveys.name as surveyName, 
    customers.companyName, 
    activities.name as activityName 
    FROM freeAnswers, 
     clients, 
     surveys, 
     customers, 
     activities 
    WHERE freeAnswers.surveyId = surveys.id 
     AND surveys.customerId = customers.id 
     AND activities.id = surveys.activityId 
     AND clients.id = freeAnswers.clientId 
     AND customers.id = 1 
    ORDER BY activityName asc 
    LIMIT 0, 10 

쿼리 내 MySQL 서버에 맞지만을 나는 젠드에서 사용하려고 할 때 프레임 워크 1.11 모델 Mysqli 준비 오류 : 피연산자에 1 개의 열이 포함되어야합니다.

제발, 누군가가 잘 달릴 수 있도록 도와 주시겠습니까?

최고 감사합니다, Elaidon

+0

검색어를 역행하십시오. 읽을 수 없습니다. 귀하의 게시물을 편집하여 추가하려고했지만 짧은 편집은 허용되지 않습니다. – Vic

답변

0

여기에 작동해야합니다 몇 가지 코드입니다. Zend_Db_SelectJOIN을 사용하지 않고 FROM 절에있는 여러 테이블 중에서 선택할 수있는 방법을 제공하지 않습니다. 이렇게하면 쿼리의 작은 부분과 관련하여 나에게 조금 해킹 당할 것입니다. 적절한 경우 JOIN을 사용하여 쿼리를 다시 작성하는 것이 가장 좋습니다. 정말 하나 개의 테이블에서 작동

->from(array('activities' => new Zend_Db_Expr($from)), 

from() 때문에, 나는 Zend_Db_Expr를 작성하고 마지막 테이블 이름과 상관 관계를 지정

$subselect = $db->select() 
        ->from('geodatas', 'districtCode') 
        ->where('zipCode = clients.zipCode') 
        ->group('zipCode') 
        ->limit(1, 0); 

    $from = $db->quoteIdentifier('freeAnswers') . ', ' . 
       $db->quoteIdentifier('clients')  . ', ' . 
       $db->quoteIdentifier('surveys')  . ', ' . 
       $db->quoteIdentifier('customers') . ', ' . 
       $db->quoteIdentifier('activities'); 

    $select = $db->select() 
       ->from(array('activities' => new Zend_Db_Expr($from)), 
         array('freeanswers.*', 
           'districtCode' => 
            new Zend_Db_Expr('(' . $subselect . ')'), 
           'clients.zipCode', 'clients.gender', 'clients.startAge', 
           'clients.endAge', 'clients.mail', 'clients.facebook', 
           'clients.customerId', 'clients.activityId', 
           'surveyName' => 'surveys.name', 'customers.companyName', 
           'activityName' => 'activities.name')) 
       ->where('freeAnswers.surveyId = surveys.id') 
       ->where('surveys.customerId = customers.id') 
       ->where('activities.id = surveys.activityId') 
       ->where('clients.id = freeAnswers.clientId') 
       ->where('customers.id = ?', 1) 
       ->order('activityName ASC') 
       ->limit(10, 0); 

나는 그것이 hackish라고하는 유일한 이유는 라인이다 표현에. Zend_Db_Expr을 전달하지 않으면 쉼표로 구분 된 테이블 이름이 잘못 인용되거나 테이블 이름 배열을 전달하면 첫 번째 테이블 만 사용됩니다. 이름이없는 Zend_Db_Expr을 전달하면 기본적으로 AS t을 사용하며이 경우에도 작동하지 않습니다. 그래서 나는 그것을 그대로 둔다.

마지막으로 언급 한 것을 제외하고 사용자가 제공 한 정확한 SQL을 리턴합니다. 여기 반환 무엇을 실제로 :

SELECT 
`freeanswers`.*, 
(SELECT `geodatas`.`districtCode` 
    FROM `geodatas` 
    WHERE (zipCode = clients.zipCode) 
    GROUP BY `zipCode` 
    LIMIT 1) AS `districtCode`, 
`clients`.`zipCode`, 
`clients`.`gender`, 
`clients`.`startAge`, 
`clients`.`endAge`, 
`clients`.`mail`, 
`clients`.`facebook`, 
`clients`.`customerId`, 
`clients`.`activityId`, 
`surveys`.`name` AS `surveyName`, 
`customers`.`companyName`, 
`activities`.`name` AS `activityName` 
FROM `freeAnswers`, 
    `clients`, 
    `surveys`, 
    `customers`, 
    `activities` AS `activities` 
WHERE (freeAnswers.surveyId = surveys.id) 
AND (surveys.customerId = customers.id) 
AND (activities.id = surveys.activityId) 
AND (clients.id = freeAnswers.clientId) 
AND (customers.id = 1) 
ORDER BY `activityName` ASC 
LIMIT 10 

은 그래서 작동하지만 결국 그것이 WHERE 조항의 대부분을 지정하는 대신 JOIN를 사용하여 다시 작성하는 것이 좋습니다.

서브 쿼리와 Zend_Db_Select을 다룰 때 최종 쿼리를 작성하기 전에 각 하위 쿼리를 고유 한 쿼리로 작성하고 나머지 부분을 처리해야하는 하위 쿼리를 삽입하기 만하면됩니다.

희망이 있습니다.

+0

안녕하세요 Drew010! 우선 답에 감사하지만 문제가 있습니다. 나는 모델 안에 있고 예제 $ db 변수를 $ this로 대체했지만 디버거에서이 오류가 발생합니다. 치명적인 오류 : 정의되지 않은 메서드 Admin_Model_Suggestions :: quoteIdentifier()를 호출하면 이유를 알 수 없습니다. – Elaidon

+0

모델 내부에서 'quoteIdentifier'를 호출 할 수있는 DB 어댑터를 반환하는 getAdapter() 메소드가있는'DbTable' 객체의 인스턴스를 얻어야합니다. 모델과 매퍼에 대한 ZF 빠른 시작 방법을 따랐다면'$ this-> getDbTable() -> getAdapter() -> quoteIdentifier (...);와 같이 보일 것입니다. 이것은 모델 설정 방법에 달려 있습니다. – drew010