2012-04-05 46 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.... 

我想通了使用GROUP_CONCAT我能得到的名稱顯示出來很容易地通過添加:

GROUP_CONCAT(op.name) as product_name 

到SELECT子句,但對我的生活我無法弄清楚如何讓小計每個公關請在產品名稱旁邊顯示。我有一種感覺,它涉及到嵌套在GROUP_CONCAT中的連接或CONCAT的組合,但我沒有嘗試過任何工作。有任何想法嗎?

@piotrm有一個想法,好像它應該工作(下同),但由於某種原因,它返回下列信息:只要我拿出s.subtotal從它拉原來的SELECT子句

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

正確的產品名稱。 JOIN查詢將產品正確地拉出與其關聯的category_id和小計。我不能把這兩個人放在一起,不要在這裏創造這個爛攤子。任何其他想法?

解決方案

@ piotrm的查詢基本上是正確的,除了GROUP_CONCAT正在尋找字符串的集合。所以最終的查詢是這樣的:

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_productsorder_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 

你的數據庫架構是相當怪異雖然,訂單表看起來可能被刪除,該日期搬到order_products,因爲每一個order_products行你必須參考訂單表。通常情況下,這是另一種方式 - 訂單表中的product_id字段引用的每個產品都有很多訂單。另外日期列中的訂單是類型varchar - 爲什麼不是日期或日期時間?

+0

order_products存儲與訂單相關的產品(一對多關係,因爲訂單可以有很多產品)。日期列是varchar,因爲我在那裏存儲unix時間戳,而不是日期時間。你的回答看起來應該可行,我會修改原始帖子以顯示發生了什麼。 – 2012-04-05 22:25:07

+0

知道了!你的SQL是正確的,但GROUP_CONCAT不能在動態列上工作。我會在原帖中發佈解決方案,但我將你的答案標記爲正確,因爲如果沒有它,我不會得到答案。謝謝! – 2012-04-06 01:35:03

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' ='' [分類名稱]'; – 2012-04-05 20:06:44

+0

btw你應該由c.id和c.name組成 – 2012-04-05 20:13:33

+0

不幸的是,也沒有做到這一點。謝謝! – 2012-04-05 20:42:32

相關問題