2009-11-03 7 views
0

2 개의 테이블과 뷰가 있습니다. product_oper에는 내가받은 제품 (id_dest이 1 일 때)과 내가 판매하는 제품 (id_src이 1 일 때)이 있습니다. product_doc 테이블에는 작업이 수행 된 날짜가 들어 있습니다.MySQL에서 사용자 변수가있는 뷰에서 선택 - 예기치 않은 결과

CREATE TABLE product_doc (
    id bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
    doc_date date NOT NULL, 
    doc_no char(16) NOT NULL, 
    PRIMARY KEY (id) 
) ENGINE=InnoDB; 

INSERT INTO product_doc (id,doc_date,doc_no) VALUES 
(1,'2009-10-07','1'), 
(2,'2009-10-14','2'), 
(3,'2009-10-28','4'), 
(4,'2009-10-21','3'); 

CREATE TABLE product_oper (
    id bigint(12) unsigned NOT NULL AUTO_INCREMENT, 
    id_document bigint(20) unsigned NOT NULL, 
    prod_id bigint(12) unsigned NOT NULL DEFAULT '0', 
    prod_quant decimal(16,4) NOT NULL DEFAULT '1.0000', 
    prod_value decimal(18,2) NOT NULL DEFAULT '0.00', 
    id_dest bigint(20) unsigned NOT NULL, 
    id_src bigint(20) unsigned NOT NULL, 
    PRIMARY KEY (id) 
) ENGINE=InnoDB; 

INSERT INTO product_oper (id,id_document,prod_id,prod_quant,prod_value,id_dest,id_src) 
    VALUES 
    (10,1,1,'2.0000', '5.00',1,0), 
    (11,3,1,'0.5000', '1.20',0,1), 
    (12,1,2,'3.0000','26.14',1,0), 
    (13,2,2,'0.5000','10.20',0,1), 
    (14,3,2,'0.3000', '2.60',0,1), 
    (15,4,2,'1.0000', '0.40',1,0); 

보기에서 나는 모든 작업과 날짜를보고 싶습니다.

CREATE VIEW product_oper_view AS 
SELECT product_oper.*, product_doc.doc_date AS doc_date, product_doc.doc_no AS doc_no 
FROM product_oper JOIN product_doc ON product_oper.id_document = product_doc.id 
WHERE 1; 

이제는 단일 제품의 작동 및 특정 날짜의 금액과 금액을보고 싶습니다.

SET @amount=0.000, @balance=0.00; 

SELECT product_oper_view.*, 
    IF(id_dest<>0, prod_quant, NULL) AS q_in, 
    IF(id_dest<>0, prod_value, NULL) AS v_in, 
    IF(id_src<>0, prod_quant, NULL) AS q_out, 
    IF(id_src<>0, prod_value, NULL) AS v_out, 
    @amount:[email protected] + IF(id_dest<>0, 1, -1)*prod_quant AS q_amount, 
    @balance:[email protected] + IF(id_dest<>0, 1, -1)*prod_value AS v_balance 
FROM product_oper_view 
WHERE prod_id=2 AND (id_dest=1 OR id_src=1) 
ORDER BY doc_date; 

I 얻을 결과 이상한 : +3 => 3 (OK) 2 행에
: -0.5 =

id, id_ prod_ prod_ id_ id_ doc_date, q_in, v_in,     q_  v_ 
    doc, quant,value,dest,src,        q_out, v_out, amount, balance 
12, 1, 3.0000, 26.14, 1, 0, '2009-10-07', 3.0000, 26.14, NULL , NULL, 3.000, 26.14 
13, 2, 0.5000, 10.20, 0, 1, '2009-10-14', NULL , NULL, 0.5000, 10.20, 2.500, 15.94 
15, 4, 1.0000, 0.40, 1, 0, '2009-10-21', 1.0000, 0.40, NULL , NULL, 3.200, 13.74 
14, 3, 0.3000, 2.60, 0, 1, '2009-10-28', NULL , NULL, 0.3000, 2.60, 2.200, 13.34 

양은
행 1에서, 0부터 시작 > 2.5 (OK)을 3 행
: +1 = "3.2 (??)의 4 행에서
: -0.3 ="2.2 (??)

,

문을 실행할 때 MySQL이 ORDER BY 절에 지정된 행의 순서를 따르지 않는 것처럼 보입니다. id 4를 가진 문서를 참조하십시오 : id 3 ('2009- 10-21 '<'2009-10-28 ')

잘못된 것이 있습니까? 아니면 MySQL의 버그입니까?

답변

0

내가 완전히 틀리지 않다면 결과 세트를 준비 할 때 마지막으로 수행 한 작업 중 하나가 ORDER입니다. 따라서 결과를 주문하기 전에 계산이 완료됩니다. 이 문제를 우회하는 올바른 방법은 subselect를 사용하는 것입니다.

SET @amount=0.000, @balance=0.00; 

SELECT p.*, 
    @amount:[email protected] + IF(p.id_dest <> 0, 1, -1) * p.prod_quant AS q_amount, 
    @balance:[email protected] + IF(p.id_dest <> 0, 1, -1) * p.prod_value AS v_balance 
FROM (
    SELECT product_oper_view.*, 
     IF(product_oper_view.id_dest <> 0, product_oper_view.prod_quant, NULL) AS q_in, 
     IF(product_oper_view.id_dest <> 0, product_oper_view.prod_value, NULL) AS v_in, 
     IF(product_oper_view.id_src <> 0, product_oper_view.prod_quant, NULL) AS q_out, 
     IF(product_oper_view.id_src <> 0, product_oper_view.prod_value, NULL) AS v_out 
    FROM product_oper_view 
    WHERE product_oper_view.prod_id = 2 
     AND (product_oper_view.id_dest = 1 OR product_oper_view.id_src = 1) 
    ORDER BY product_oper_view.doc_date 
) AS p 
+0

subselect와 함께 작동합니다. ORDER BY를 뷰에 넣으려고했지만 효과가 없다는 것을 알았습니다. –

+0

뷰가'MERGE' 알고리즘 ('TEMPTABLE' 알고리즘과는 대조적으로)을 사용하기 때문에'ORDER BY'를 뷰 정의로 전달하는 것은 아무 효과가 없습니다. 'MERGE' 뷰는 뷰 SQL 문을 말 그대로 * 주어진 SQL 쿼리로 병합하여 실행됩니다. –

관련 문제