2014-09-24 4 views
1

xcart_order_details에 저장된 활성 판매 주문의 재고 수량을 계산하려고합니다. 또한 처리 된 'P'또는 대기열에있는 'Q'상태의 x 일 내에있는 주문과 스톡 유형이 특정 위치와 일치하는 경우에만 재고를 계산하려고합니다. C1 재고, C2 재고 등.조인 및 중첩 된 쿼리를 사용하여 수량 계산

예전의 xcart 데이터베이스에서는 비교적 간단했습니다.

SELECT COUNT(`amount`) 
FROM `xcart_order_details` 
WHERE `productid` IN (
    SELECT `productid` 
    FROM `xcart_products` WHERE `orderid` IN 
    (SELECT `orderid` 
    FROM `xcart_orders` 
    WHERE `date` > ".$date_range." 
     AND (`status` = 'P' 
      OR `status` = 'Q')) 
    AND (LOWER(param01) = 'c1 stock' 
     OR LOWER(param01) = 'c2 stock' 
     OR LOWER(param01) = 'g stock' 
     OR LOWER(param01) = 'stock') 
    AND `productid` = ".$safe_prodid.") 

이 쿼리가 작동했습니다. 그러나 이제 우리의 재고 위치는 xcart_extra_field_values라고하는 다른 테이블에 저장되므로 fieldid = 5 인 경우 검색해야합니다.

fieldid = 5 인 xcart_extra_field_values에서 값 필드를 가져 오기 위해 조인을 사용하고 위 쿼리에서 수행중인 작업을 시도했지만 작동하지 않습니다.

SELECT COUNT(`a.amount`) 
FROM xcart_order_details a, 
    xcart_extra_field_values b 
WHERE a.productid IN (
    SELECT productid 
    FROM xcart_products WHERE orderid IN 
    (SELECT orderid 
    FROM xcart_orders 
    WHERE date > 1409529600 
     AND (status = 'P' 
      OR status = 'Q')) 
    AND (LOWER(b.value) = 'c1 stock' 
     OR LOWER(b.value) = 'c2 stock' 
     OR LOWER(b.value) = 'g stock' 
     OR LOWER(b.value) = 'stock') 
    AND (a.productid = b.productid) 
    AND (a.productid = 4169) 
    AND (b.fieldid = 5) 

불행하게도이 쿼리가 작동하지 않습니다, 나는 그것을 구문 문제를 알고 있지만, 내가지고있어 오류가 전혀 도움이되지 않습니다.

내가 뭘 잘못하고 있는지 알 수있는 사람이 있습니까?

+0

어떤 오류가 발생합니까? – Arion

+0

내가 얻고 : "SQL 구문에 오류가있어,"at line 19 "근처에서 사용할 올바른 구문에 대해서는 MySQL 서버 버전에 해당하는 설명서를 확인하십시오. 어떤 것이 의미가 있는지 , 그 당시에는 불분명했다. –

+0

금액이있는 레코드를 계산하는 것은 이상한 일입니다. WHERE 절에서 NULL을 제외하고 (AND AND IS NOT NULL)) count 레코드 ('COUNT (*) ')를 사용하면 테이블에서 다른 값을 선택하지 않아도됩니다. ') 대신. 금액이 null이 아닌 누적 값보다 count 레코드 (다시 'COUNT (*)')보다 NULL이 아닌 경우. (물론 합계를 계산하려면 합계를 계산할 수 있습니다.) –

답변

0

두 테이블을 조인하는 기준이 누락되었습니다. 테이블 xcart_extra_field_values에 xcart_order_details_id가 있다고 가정하고이를 사용하십시오.

결국 가입 할 필요조차 없습니다.

SELECT COUNT(`amount`) 
FROM `xcart_order_details` 
WHERE `productid` IN 
(
    SELECT `productid` 
    FROM `xcart_products` 
    WHERE `orderid` IN 
    (
    SELECT `orderid` 
    FROM `xcart_orders` 
    WHERE `date` > ".$date_range." 
    AND `status` IN ('P','Q') 
) 
AND `productid` = ".$safe_prodid." 
AND EXISTS 
(
    SELECT * 
    FROM xcart_extra_field_values v 
    WHERE v.xcart_order_details_id = xcart_order_details.id 
    AND fieldid = 5 
    AND LOWER(param01) IN ('c1 stock','c2 stock','g stock','stock') 
); 

을 BTW : 당신은 xcart_order_details 결과가있는 특정 상세 값의 기록이 존재 원하는 당신은 금액을 얼마나 많은 순서 세부 기록을 계산?

+0

이것은 정확할 수 있지만 완전히 다른 방식으로 수행하고있는 것처럼 보입니다. 이제 내 쿼리가 작동합니다. 더 효율적인 지 알아보기 위해이 방법을 살펴 보겠습니다. 내 테이블에 조인 할 기준이 내 쿼리에 있습니다 (a.productid = b.productid) –

+0

이제 언급했습니다 ;-) 내 쿼리가 원래 쿼리와 정확히 일치하지 않습니다.그나저나 당신 것도 마찬가지입니다. 광산은 원하는 날짜 범위와 상태 * 및 *의 모든 기록을 가져옵니다. 특정 주식 항목에 대해 원하는 기간 및 상태 *가 있어야 할 때 특정 주식 항목이 있습니다. 원하는 날짜 범위와 원하는 위치에 대해 xcart_extra_field_values에 레코드가있는 상태의 쿼리가 생성됩니다. 나는 당신에게 당신의 대답에 대한 추가 코멘트를 주겠다. –

+0

그래, 나는 내 자신의 답을 바로 잡았다. xcart_extra_field_values는 항상 각 제품에 대한 항목을 포함합니다. 기본적으로 재고가 특정 창고 위치에있는 x 일 동안 활성 고객 주문을 통해 재고를 계산합니다. –

0

해결되었습니다.

SELECT COUNT(a.amount) 
FROM xcart_order_details a, 
    xcart_extra_field_values b 
WHERE a.productid IN 
    (SELECT productid 
    FROM xcart_products 
    WHERE orderid IN 
     (SELECT orderid 
      FROM xcart_orders 
      WHERE date > 1409529600 
      AND (status = 'P' 
       OR status = 'Q')) 
     AND (LOWER(b.value) = 'c1 stock' 
      OR LOWER(b.value) = 'c2 stock' 
      OR LOWER(b.value) = 'g stock' 
      OR LOWER(b.value) = 'stock')) 
     AND (a.productid = b.productid) 
     AND (a.productid = 4169) 
     AND (b.fieldid = 5) 

첫째, 내가 쿼리에 두 개의 중첩 된 나는 내 쿼리의 끝에서 브래킷을 실종됐다, 나는 그것을 좋아하지 않았다, COUNT 내 a.amount 주위에 무덤 악센트를 제거 할 필요가 있었다. 내 검색어를 나란히 볼 때 누락 된 대괄호 만 나타났습니다.

편집 : 내 중첩 된 IN 절 외부로 조인을 이동했습니다. 내포 된 중첩 된 절을 의미가 없으므로 밖으로 이동했습니다.

+0

1. 올바르게 연결되었는지 확인하십시오. xcart_order_details와 xcart_extra_field_values는 productid에 의해 연결될뿐만 아니라, 그렇지 않습니까? 2. 교차 조인을 수행 한 다음 IN 절 내부의 조인 된 결과 레코드를 버리는 것은 이상한 일입니다. 가능하지만 읽을 수는 없습니다. 어쨌든 의도 된 것처럼 보이지 않으므로 제 3자가 쿼리의 결함을 추측 할 수 있습니다. 3. 20 년 전에 명시 적 조인 (INNER JOIN, CROSS JOIN 등)에 의해 표준 SQL로 대체 된 오류가 발생하기 쉬운 콤마로 분리 된 조인 구문을 피해야합니다. –

+0

extra_field_values ​​테이블에는 항상 productid에 일치하는 항목이 포함되므로 아무 것도 삭제되지 않습니다. 어쨌든 Join은 IN 절 안에있을 필요는 없으며, 단지 내 주 IN 절의 끝을 내 join을 수행하기 직전으로 옮겨야합니다. –

+0

"버려진"이란 말은 두 테이블을 교차 결합하는 것을 의미합니다. 각 행에 1000 개의 행이 있으면 백만 개의 결과 레코드를 얻지 만 결과에서 레코드를 버립니다. IN 절을 사용하면 그렇게 할 수 있습니다.하지만 IN 절에서는 매우 드문 바깥 쪽의 값 (문제의 레코드에서 나온 값)을 사용합니다. 그것은 속임수이며 작동하지만, 당신은 그것에 대해 조심하고 실제로 무엇을하고 있는지 알아야합니다. 매우 읽기 쉽거나 유지 보수가 불가능한 것으로 간주되지 않습니다. –

관련 문제