在我开始之前;这不是你正常的MySQL JOIN问题......好吧,尽管我不知道基本的JOIN问题。
基本上我的问题归结为我正在运行的查询,尽管存在数据,但它似乎并未返回所有外部连接。奇怪的是,如果我使用内连接,则返回数据;如果我使用汇总函数(使用外连接时),也会返回数据。
我们正在运行MariaDB:
mysqld --version mysqld Ver 10.0.12-MariaDB-1~wheezy-log for debian-linux-gnu on x86_64 (mariadb.org binary distribution)
我已经能够在一个更简单的查询中复制问题,我将在下面详细介绍(简单的票证/交易表和客户/卡表):
表格如下:
-------------------
|CUSTOMER |
-------------------
|*card_number |
-------------------
-------------------
|TICKET |
-------------------
|*id |
|card_number |
|transaction_value|
-------------------
第一个查询正在使用常规外部联接,它返回所有销售(包括非卡销售)。这是我想要收到的数据,但是如果查看返回的值,则票证ID 8没有附加卡号(即使计数字段表示已找到它)。
SELECT ticket.id,
ticket.transaction_value,
customer.card_number,
COUNT(customer.card_number)
FROM ticket
LEFT OUTER JOIN customer ON ticket.card_number = customer.card_number
WHERE DATE(ticket.timestamp) = "2014-11-09"
GROUP BY ticket.id;
id, transaction_value, card_number, count
4 , 205.13 , {null} , 0
5 , 116.04 , xxx4785 , 1
6 , 74.97 , xxx0281 , 1
7 , 19.99 , xxx6836 , 1
8 , 55.98 , {null} , 1
9 , 13.59 , {null} , 0
第二个查询使用内部联接,该联接仅返回附有卡片的销售,但在这种情况下,我们可以看到故障单8现在具有卡号。为什么它没有出现在第一个查询中?
SELECT ticket.id,
ticket.transaction_value,
customer.card_number,
COUNT(customer.card_number)
FROM ticket
JOIN customer ON ticket.card_number = customer.card_number
WHERE DATE(ticket.timestamp) = "2014-11-09"
GROUP BY ticket.id;
id, transaction_value, card_number, count
5, 116.04 , xxx4785 , 1
6, 74.97 , xxx0281 , 1
7, 19.99 , xxx6836 , 1
8, 55.98 , xxx0273 , 1
最后我决定尝试使用汇总功能:在这种情况下,我再次使用外部联接,发现票证8再次附加了卡号。我重复了MIN
并得到了相同的结果。
SELECT ticket.id,
ticket.transaction_value,
MAX(customer.card_number),
COUNT(customer.card_number)
FROM ticket
LEFT OUTER JOIN customer ON ticket.card_number = customer.card_number
WHERE DATE(ticket.timestamp) = "2014-11-09"
GROUP BY ticket.id;
id, transaction_value, card_number, count
4 , 205.13 , {null} , 0
5 , 116.04 , xxx4785 , 1
6 , 74.97 , xxx0281 , 1
7 , 19.99 , xxx6836 , 1
8 , 55.98 , xxx0273 , 1
9 , 13.59 , {null} , 0
有人可以了解这里发生的事情吗?我真的希望能够解决这个问题,而不必诉诸复杂的解决方案,如多个查询或添加特殊的汇总函数等。(在发生这种情况之前,外连接的情况很好)。
答案 0 :(得分:1)
看起来我可能找到了罪魁祸首; Maria 10.x中存在一个错误,当使用group by MariaDB Bug Report时,会导致外连接中省略结果。感谢Aziz提出了一些很好的建议并帮助我。希望这可能会帮助那些和我一样困惑的人!
更新:我测试了MariaDB 10.0.21并确认错误已经修复。
答案 1 :(得分:0)
您正在GROUP BY
上执行ticket.id
,但您的SELECT
列表也包含非ticket.transaction_value, customer.card_number
的非分组列。这导致数据不一致。传统上(在其他RDBMS服务器中)这会产生语法错误,但是MySql允许它,因此查询编写者必须确保他们自己处理这种情况。
参考:http://dev.mysql.com/doc/refman/5.0/en/group-by-handling.html
在标准SQL中,包含GROUP BY子句的查询不能引用选择列表中未在GROUP BY子句中命名的非聚合列。
MySQL扩展了GROUP BY的使用,因此选择列表可以引用未在GROUP BY子句中命名的非聚合列。
服务器可以自由选择每个组中的任何值,因此除非它们相同,否则所选的值是不确定的。