2012-04-05 4 views
1

MySQL 쿼리에 대한 도움이 필요합니다. 나는 세 개의 테이블을 가지고 있습니다 :MySQL 일대 다 관계 : GROUP_CONCAT 또는 JOIN 또는 둘 다?

`product_category` (
    `id` int(11) NOT NULL auto_increment, 
    `name` varchar(255) NOT NULL, 
PRIMARY KEY (`id`) 
); 

`order_products` (
    `id` int(11) NOT NULL auto_increment, 
    `name` varchar(255) NOT NULL, 
    `qty` int(11) NOT NULL, 
    `unit_price` decimal(11,2) NOT NULL, 
    `category` int(11) NOT NULL, 
    `order_id` int (11) NOT NULL, 
    PRIMARY KEY (`id`) 
); 

`orders` (
    `id` int(11) NOT NULL auto_increment, 
    `date` varchar(255) NOT NULL, 
    PRIMARY KEY (`id`) 
); 

제품 범주별로 (특정 날짜 범위 내에서) 모든 주문의 부분합을 계산 한 쿼리가있었습니다. 그것은이처럼 보였다 :

SELECT 
    SUM(op.unit_price * op.qty) as amt, 
    c.name as category_name 
FROM 
    order_products op, 
    product_category c, 
    orders o 
WHERE 
    op.category = c.id 
AND 
    op.order_id = o.id 
AND 
    o.date > 'xxxxxxx' 
GROUP BY 
    c.id 

이 잘 작동하지만, 지금은 내가이 같은 결과를 얻을 수 있도록 각 행에 개별 제품과 합계를 추가 할 : 내가 알아 낸

c.name|amt|op.name (1) - op.subtotal (1), op.name (2), op.subtotal (2), etc.... 

을 SELECT 절에

GROUP_CONCAT(op.name) as product_name 

하지만 내 인생 내가 각 홍보의 합계를 얻을 방법을 알아낼 수 없습니다 : 추가하여 아주 쉽게 나는 이름이 표시 얻을 수 GROUP_CONCAT를 사용하여 제품 이름 옆에 oduct가 나타납니다. GROUP_CONCAT 안에 중첩 된 조인 또는 CONCAT의 조합이 포함 된 느낌이 들지만 시도한 것은 아무것도 없습니다. 어떤 아이디어?

@piotrm는 (아래) 작업을해야처럼 보였다 아이디어를 가지고 있지만 어떤 이유로 다음과 같은 반환 마자 나는 그것을 끌어 원래 SELECT 절에서 s.subtotal을 걸릴

SELECT `subtotals` 
FROM `product_category` 
WHERE `c`.`category_name` = 'Fragrance'AND.`amt` = '23164.50'AND.`subtotals` = CAST( 0x6c6f76656c696c7920454454202d203631302e30302c20466f72657665726c696c79202e313235206f7a2045445020726f6c6c657262616c6c202d20313831372e35302c20666f72657665726c696c79206361636865706f74202d2039302e30302c20666f72657665726c696c7920312f38206f756e63652070617266756d206f696c20726f6c6c657262616c6c202d20313833302e30302c20666f72657665726c696c792070657266756d696e6720626f6479206c6f74696f6e202d203938312e30302c20666f72657665726c696c7920332e34206f756e6365206561752064652070617266756d207370726179202009202d203535382e30302c20666f72657665726c696c79205363656e74656420566f746976652043616e646c65202d203132302e30302c20454450202620426f6f6b20736574202d203334332e30302c20666f72657665726c696c7920332e34206f756e6365206561752064652070617266756d207370726179202d2031363831352e3030 AS 
BINARY) ; 

을 올바른 제품 이름. JOIN 쿼리는 관련된 category_id 및 부분합을 사용하여 제품을 올바르게 가져옵니다. 이 엉망진창을 만들지 않고 함께 두 사람을 만날 수는 없습니다. 다른 생각? GROUP_CONCAT 문자열의 집합을 찾고 제외

piotrm의 쿼리 @ 솔루션

는 기본적으로 옳았다. 그래서 최종 쿼리는 다음과 같이 보았다 :

SELECT c.name AS category_name, 
     SUM(s.subtotal) AS amt, 
     GROUP_CONCAT(CONCAT(s.name, ' - ', cast(s.subtotal as char)) SEPARATOR ', ')       AS subtotals 
FROM 
     product_category c 
JOIN 
    (SELECT op.category, op.name, sum(op.qty*op.unit_price) AS subtotal 
FROM order_products op 
JOIN orders o ON o.id = op.order_id 
WHERE o.date > '0' 
GROUP BY op.category, op.name) s 
ON s.category = c.id 
GROUP BY c.name 

답변

0

당신이 테이블 정의에서 언급하지 않았다 당신의 order_products 테이블에 order_id 필드도있다.

SELECT c.name AS category_name, 
      SUM(s.subtotal) AS amt, 
      GROUP_CONCAT(CONCAT(s.name, ' - ', s.subtotal) SEPARATOR ', ') AS subtotals 
FROM 
    product_category c 
JOIN 
    (SELECT op.category, op.name, sum(op.qty*op.unit_price) AS subtotal 
    FROM order_products op 
    JOIN orders o ON o.id = op.order_id 
    WHERE o.date > '2012-03-31' 
    GROUP BY op.category, op.name) s 
    ON s.category = c.id 
GROUP BY c.name 

귀하의 DB 스키마가 아주 이상해가 제거 될 수 모든 order_products 행에 대해 당신이 주문 테이블에 대한 참조를 가지고 있기 때문에 그 날짜가, order_products로 이동처럼하지만, 주문 테이블은 같습니다처럼 쿼리는 다음 보일 것입니다. 일반적으로 다른 방법입니다. orders 테이블의 product_id 필드에서 참조하는 모든 제품에 대해 많은 주문이 있습니다. 또한 orders의 date 열은 varchar 유형입니다. date 또는 datetime이 아닌 이유는 무엇입니까?

+0

order_products는 주문과 관련된 제품 (주문이 많은 제품을 가질 수 있으므로 일대 다 관계)을 저장합니다. datetime이 아니라 unix timestamp를 저장하기 때문에 날짜 열은 varchar입니다. 귀하의 대답은 제대로 된 것 같아요, 나는 원래 게시물을 수정하여 무슨 일이 일어나는지 보여줄 것입니다. –

+0

알았습니다!SQL에 돈이 들었지만 GROUP_CONCAT은 동적 열에서 작동하지 않습니다. 나는 원래의 게시물에 해결책을 게시 할 것이지만 나는 당신의 답을 옳은 것으로 표시하고있다. 왜냐하면 나는 그것없이 거기에 가지 않았기 때문이다. 감사! –

0

시도 : 조회에서 추측

SELECT 
    SUM(op.unit_price * op.qty) as amt, 
    c.name as category_name, 
    group_concat(concat(op.name, '-', op.qty, ',' , 
       op.unit_price*op.qty) separator '|') 
    ... 
+0

감사합니다. 이미 시도했지만 작동하지 않습니다. 다음의 데이터를 가지고 그 컬럼에 "blob"을 반환합니다 :'code' SELECT'subtotal' FROM'order_products' WHERE .'amt' = '##. ###' AND'c'.category_name' = [카테고리 이름] '; –

+0

btw c.id와 c.name 모두로 그룹화해야합니다. –

+0

불행히도 그렇게하지 않았습니다. 감사! –