2010-01-26 29 views
0

我知道這不是一個創建表的好習慣,所以請先把它放在一邊。在MySQL中使用子查詢進行選擇

我有一個表,讓說表A和B表

Table A : 
| ID | fk_tableB_ID | title 
------------------------- 
| 10 | 1,2   | title 1 
| 11 | 3   | title 2 

Table B : 
| ID | category 
--------------- 
| 1 | cat1 
| 2 | cat2 
| 3 | cat3 

我嘗試此查詢:

SELECT 
    a.ID, 
    a.title, 
    (
     SELECT 
      group_concat(b.category) 
     FROM 
      tableB B 
     WHERE 
      B.ID IN (a.fk_tableB_ID) 
    ) as category 
FROM 
    tableA a 

它返回:

| ID | category | title 
----------------------- 
| 10 | cat1  | title1 
| 11 | cat3  | title2    

但是,這不是我想。我想要的是

| ID | category | title 
----------------------- 
| 10 | cat1,cat2 | title1 
| 11 | cat3  | title2 

請幫忙,什麼是正確的MySQL查詢代碼,所以我可以得到上面的表。 THX提前

回答

0

是的,這幾乎是如何工作,如果你在一個單元格中存儲多個值。節省您的麻煩並設計您的表,以便每行只有一個fk_tableB_ID。您可以將這些值合併到您選擇的編程語言的一行中,因爲它在MySQL中不可行。

像這樣的東西應該爲你工作:

Table A : 
| ID | page_ID | fk_tableB_ID | title 
------------------------- 
| 7 | 10  | 1   | title 1 
| 8 | 10  | 2   | title 1 
| 9 | 11  | 3   | title 2 

Table B : 
| ID | category 
--------------- 
| 1 | cat1 
| 2 | cat2 
| 3 | cat3 

而且你的查詢將大大簡化:

SELECT 
    a.page_ID, 
    b.category, 
    a.title 
FROM 
    table_a a 
LEFT JOIN 
    table_b b 
ON 
    a.fk_tableB_ID = b.ID 

如果你碰巧使用PHP,做到結合在了那裏。這應該工作:

$r = mysql_query('SELECT ... '); 

$result = array(); 

while($row = mysql_fetch_assoc($r)) { 
    $result[$row['page_ID']]['title'] = $row['title']; 
    $result[$row['page_ID']]['categories'][] = $row['category']; 
} 

應該導致這樣的事情,其中​​:

Array 
(
    [10] => Array 
     (
      [title] => title 1 
      [categories] => Array 
       (
        [0] => cat1 
        [1] => cat2 
       ) 

     ) 

    [11] => Array 
     (
      [title] => title_2 
      [categories] => Array 
       (
        [0] => cat3 
       ) 

     )  
) 

如果你想要使用數組來建立類似的例子的表,你可以使用這個:

echo "| ID  | category   | title\n"; 
echo "----------------------------------------\n"; 
foreach($array as $page_ID => $row) { 
    echo '| '.str_pad($page_ID, 7); 
    echo '| '.str_pad(implode(',', $row['categories']), 20); 
    echo '| '.$row['title']."\n"; 
} 

將輸出這樣的:

| ID  | category   | title 
---------------------------------------- 
| 10  | cat1,cat2   | title_1 
| 11  | cat3    | title_2 

這正是你想要的。當然,你可能想輸出一個HTML表格,但你明白了。

+0

的'你建議的表A是不好的設計,例如每個標題都存儲多次。也許還有一個有很多文字的描述字段。你創造冗餘!第三張表是一個更好的設計。 – 2010-01-26 08:07:58

+0

@Felix,你說的對,這只是一種方法,只需要最少的修改即可完成他想要的任務。第三張桌子確實是一個更好的解決方案。 – 2010-01-26 08:12:44

+0

Thx對你的答案真的有幫助。我知道這是一張糟糕的桌子,但有時候我會得到像這樣的桌子(來自其他程序員的舊腳本)。我想也許我可以做一個單一的查詢,但現在我知道它不能。 – aprian 2010-01-27 06:43:56

0

一個更好的方式來做到這將是在中間有另一個表稱爲像「a_has_category」

Table a : 
| ID | title 
--------------- 
| 10 | title 1 
| 11 | title 2 

Table category : 
| ID | category 
--------------- 
| 1 | cat1 
| 2 | cat2 
| 3 | cat3 

Table a_has_Category : 
| ID | fk_a | fk_category 
--------------- 
| 1 | 10 | 1 
| 2 | 10 | 1 
| 3 | 11 | 2 

然後用一對夫婦的內部連接建立查詢

SELECT a.title, B.category FROM a 
INNER JOIN a_has_category 
ON fk_a = a_ID 
INNER JOIN category 
ON fk_category = category_ID 

將結果返回後,使用PHP的IMPLODE函數將類別之間用逗號連接成一個字符串。

0

我知道你不想聽到這個,但表中的多個值不是一個好的設計,特別是如果這個字段引用另一個表。
如果你想創建一個多一對多的關係,你需要一箇中間表:

Table A : 
| ID | title 
------------ 
| 10 | title 1 
| 11 | title 2 


Table B : 
| ID | category 
--------------- 
| 1 | cat1 
| 2 | cat2 
| 3 | cat3 

Table A_B: 
| fk_tableA_ID | fk_tableB_ID 
----------------------------- 
| 10   | 1 
| 10   | 2 
| 11   | 3 

我不認爲這是可以做到你想做的事,單個查詢(可能在存儲過程),但讓我們看看別人提出了什麼。

只有一個字段值被稱爲first normal form (1NF)。這是數據庫優化的第一步。

0

這樣做的方式你試圖做的問題是IN函數需要一個數組。如果你真的需要走這條路線,你將不得不在字符串上運行一個函數來創建一個數組,然後在IN語句中使用它。

一個例子是在這裏http://forums.mysql.com/read.php?60,78776,242420#msg-242420

但我會建議添加鏈接表來代替。

0

如前所述,在一列中有多個外鍵是不好的設計,你必須使用n:m表。 看到這個表結構,例如:(是的,我留下了一些指標:)

CREATE TABLE IF NOT EXISTS `a` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(50) NOT NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ; 

INSERT INTO `a` (`id`, `title`) VALUES (1, 'first row'), (2, 'second row'), (3, 'third row'), (4, 'fourth row'); 



CREATE TABLE IF NOT EXISTS `ab` ( `a_id` int(11) NOT NULL, `b_id` int(11) NOT NULL) ENGINE=MyISAM DEFAULT CHARSET=utf8; 



INSERT INTO `ab` (`a_id`, `b_id`) VALUES (1, 1), (1, 2), (1, 4), (2, 5), (3, 5), (4, 6), (4, 5), (3, 6); 


CREATE TABLE IF NOT EXISTS `b` ( `id` int(11) NOT NULL AUTO_INCREMENT, `category` varchar(50) NOT NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ; 


INSERT INTO `b` (`id`, `category`) VALUES (1, 'Cat1'), (2, 'Cat2'), (3, 'Cat3'), (4, 'Cat4'), (5, 'Cat5'), (6, 'Cat6'); 

然後你可以使用此查詢:

SELECT a.id, a.title, group_concat(b.category) 
FROM a 
LEFT JOIN ab ON a.id = ab.a_id 
LEFT JOIN b ON b.id = ab.b_id 
GROUP BY a.id; 

導致:

id title group_concat(b.category) 
1 first row Cat4,Cat1,Cat2 
2 second row Cat5 
3 third row Cat5,Cat6 
4 fourth row Cat5,Cat6