![](/img/trans.png)
[英]MySQL Join returning ALL data from left table and whatever is found in right table
[英]MySQL JOIN -> Get all data from right table even if there is no match
我有兩個表,一個表包含數據(A) ,另一個表具有類別(B) ,這些類別屬於其中一個類別或未分類。 我需要進行簡單的統計,因此我正在使用JOIN從表A獲取所有數據並將其與表B聯接。
我需要的是,即使A中沒有匹配項,我也想在圖表上顯示B中的所有類別(計數= 0,但需要顯示它們)。
因此,如果沒有具有該類別ID的項目,它根本不會顯示該類別,但是即使它有0個項目,我也需要顯示它。
我用UNION嘗試了LEFT JOIN,RIGHT JOIN,但都沒有用。
表A
id | some | irrelevant | data | category
-----------------------------------------
1 | | | | 0
2 | | | | 0
3 | | | | 1
4 | | | | 2
5 | | | | 3
6 | | | | 3
. . . . . . . . . . .
表B
id | title | color
---------------------
1 | Cat 1 | #FFFFFF
2 | Cat 2 | #FF00FF
3 | Cat 3 | #FF0000
4 | Cat 4 | #00FF00
5 | Cat 5 | #00FFFF
6 | Cat 6 | #000000
7 | Cat 7 | #FFFF00
有了這些數據,我想得到類似的東西:
Array ( [category] => 0 [count] => 3 [title] => [color] => )
Array ( [category] => 1 [count] => 1 [title] => Cat 1 [color] => #FFFFFF )
Array ( [category] => 2 [count] => 1 [title] => Cat 2 [color] => #FF00FF )
Array ( [category] => 3 [count] => 2 [title] => Cat 3 [color] => #FF0000 )
Array ( [category] => 4 [count] => 0 [title] => Cat 4 [color] => #00FF00 )
Array ( [category] => 5 [count] => 0 [title] => Cat 5 [color] => #00FFFF )
Array ( [category] => 6 [count] => 0 [title] => Cat 6 [color] => #000000 )
Array ( [category] => 7 [count] => 0 [title] => Cat 7 [color] => #FFFF00 )
但這就是我真正得到的:
Array ( [category] => 0 [count] => 3 [title] => [color] => )
Array ( [category] => 1 [count] => 1 [title] => Cat 1 [color] => #FFFFFF )
Array ( [category] => 2 [count] => 1 [title] => Cat 2 [color] => #FF00FF )
Array ( [category] => 3 [count] => 2 [title] => Cat 3 [color] => #FF0000 )
這是電話 :
"SELECT category, COUNT(*) AS count, title, color FROM A LEFT JOIN B ON B.id=A.category GROUP BY category"
PS .:再一次,我也實現了RIGHT連接,並且實現了RIGHT和LEFT連接的UNION。 另外,表的名稱很長,不能在調用中作為A.category等真正使用它們。
有沒有不用兩個SQL調用和兩個循環的方法嗎? 我真的不想這么做。
謝謝。
那呢:
MySQL 5.5.32模式設置 :
CREATE TABLE TableA
(`id` int, `category` int)
;
INSERT INTO TableA
(`id`, `category`)
VALUES
(1, 0),
(2, 0),
(3, 1),
(4, 2),
(5, 3),
(6, 3)
;
CREATE TABLE TableB
(`id` int, `title` varchar(5), `color` varchar(7))
;
INSERT INTO TableB
(`id`, `title`, `color`)
VALUES
(1, 'Cat 1', '#FFFFFF'),
(2, 'Cat 2', '#FF00FF'),
(3, 'Cat 3', '#FF0000'),
(4, 'Cat 4', '#00FF00'),
(5, 'Cat 5', '#00FFFF'),
(6, 'Cat 6', '#000000'),
(7, 'Cat 7', '#FFFF00')
;
查詢1 :
SELECT TableB.id as category, count(distinct TableA.id) as count,title,color
FROM
(SELECT * FROM TableB
UNION
SELECT 0 as id, '' as title, '' as color) AS TableB
LEFT OUTER JOIN TableA on TableB.id = TableA.category
GROUP BY TableB.id, title, color
ORDER BY TableB.id
結果 :
| CATEGORY | COUNT | TITLE | COLOR |
|----------|-------|-------|---------|
| 0 | 2 | | |
| 1 | 1 | Cat 1 | #FFFFFF |
| 2 | 1 | Cat 2 | #FF00FF |
| 3 | 2 | Cat 3 | #FF0000 |
| 4 | 0 | Cat 4 | #00FF00 |
| 5 | 0 | Cat 5 | #00FFFF |
| 6 | 0 | Cat 6 | #000000 |
| 7 | 0 | Cat 7 | #FFFF00 |
此外,您可以在TableB中添加ID為0的類別,而不是使用UNION SELECT 0 as id, '' as title, '' as color
[更新]同時添加創建數據SQL和下面的SQL查詢以證明數據:
要添加測試數據,請運行以下SQL命令:
DROP TABLE junk_category;
CREATE TABLE junk_category (
id INT PRIMARY KEY,
name VARCHAR(32) NOT NULL
);
INSERT INTO junk_category (id,name) VALUES (1,'Cat 1'), (2,'Cat 2'), (3, 'Cat 3'), (4, 'Cat 4');
DROP TABLE junk_data;
CREATE TABLE junk_data (
id INT PRIMARY KEY,
name VARCHAR(32) NOT NULL,
category INT NULL,
INDEX byCategory (category)
);
INSERT INTO junk_data (id, name, category)
VALUES
(1,'one',1),
(2,'two',1),
(3,'three',1),
(4,'four',2),
(5,'five',2),
(6,'six',3),
(7,'seven',NULL),
(8,'eight',NULL);
要查詢測試數據:
SELECT 'Uncategorized' AS category, COUNT(*) AS count
FROM junk_data A
WHERE A.category IS NULL
UNION
SELECT B.name AS category, COUNT(DISTINCT A.id) AS count
FROM junk_category B
LEFT JOIN junk_data A ON A.category=B.id
GROUP BY category
我之前給您的查詢中唯一需要更改的是DISTINCTA.id。 我錯過了以前做的粘貼操作。 如果沒有DISTINCT A.id,類別本身將計為1。DISTINCT將其限制為數據表。 但是,您說您看到的是3 ...但是查詢不會“復制”,並且應該不是3的查詢也不會是3 ...所以如果您看到的3不應有的查詢,則有一些其他問題。
[更新2015-03-03]
如果您沒有從此查詢中獲取所有類別:
SELECT B.name AS category, COUNT(DISTINCT A.id) AS count
FROM junk_category B
LEFT JOIN junk_data A ON A.category=B.id
GROUP BY category
不會返回所有類別的原因只有一個: 如果它們的名稱不是唯一的 。 上面唯一的過濾器是GROUP BY
。
但是,我意識到我可能對您感到困惑,因為我正在命名B.name AS category
,這是您其中一列的名稱。 GROUP BY
實際上是GROUP BY B.name
。 因此,丟失任何條目的唯一方法是它們具有相同的B.name
。 因此,無論如何,您的GROUP BY
必須位於B表上,而不是A表上。
在沒有看到您的實際查詢並查看您的GROUP BY或WHERE是否設置了其他限制的情況下,我無能為力 。 或利用我的install-junk sql並確保獲得相同的結果,然后嘗試找出我的查詢與實際查詢在做什么之間的差異。
這個答案不是最好的選擇,但是如果沒有人知道如何使用單個查詢和循環執行我想做的事情,我想提供它。
知道我用while循環“解決了”(這正是我不想使用的循環),但實際上看起來像我想要的是不可能的...
$get_stats = dbquery("SELECT COUNT(*) AS count, category FROM XXX GROUP BY category");
$get_cats = dbquery("SELECT * FROM YYYYY");
$categories = array();
$stats_arr = array();
while ($cat = dbarray($get_cats)){
$categories[$cat['id']] = array($cat['title'], $cat['color']);
$stats_arr[$cat['id']] = array('count' => 0, 'title' => $cat['title'], 'color' => $cat['color']);
}
while ($stats = dbarray($get_stats)){
if ($stats['category'] === "0"){
$stats_arr[0] = array('count' => $stats['count'], 'title' => 'Uncategorized', 'color' => '#FFFFFF');
}else{
$stats_arr[$stats['category']] = array('count' => $stats['count'], 'title' => $categories[$stats['category']][0], 'color' => $categories[$stats['category']][1]);
}
}
ksort($stats_arr);
foreach ($stats_arr as $id => $data) {
// Code here
}
我仍然想使其工作而無需所有這些循環。
現在還可以,因為它在我已經在循環槽類別的頁面上,但是它仍然添加了2個循環,我想在單獨的頁面上使用它,因此我需要使用單個查詢+循環來解決它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.