我和我有两张桌子。假设有一个动作列表(我工作的原始表有一个发送和接收的消息列表),另一个是用户表,其中包含用户的全名。我已经复制了我现在所拥有的问题。
在actions表(消息表)中找到的用户可能不在users表中。我正在使用子查询来针对actions表的原始查询中的用户名选择用户的全名。当actions表中的用户不在users表中时,MySQL返回 NULL ,这是预期的。但相反,我希望它返回原始用户名。
说,praveen
在users表和actions表中都有。所以,我得到这样的结论:Praveen Kumar likes something.
。说,我有另一个用户名bluff
,用户表中没有该用户名,操作就是这样:NULL shares something.
。在这里,而不是 NULL ,是否可以返回用户名本身,如bluff shares something.
?
此处提供了我的SQL Fiddle,架构详细信息和其他参考资料。如果我能以更好的方式做到这一点,请告诉我。感谢。
MySQL 5.5.30架构设置
CREATE TABLE `users`
(`username` varchar(15), `fullname` varchar(15))
;
INSERT INTO `users`
(`username`, `fullname`)
VALUES
('praveen', 'Praveen Kumar'),
('jeff', 'Jeff Atwood')
;
CREATE TABLE `actions`
(`user` varchar(7), `action` varchar(7))
;
INSERT INTO `actions`
(`user`, `action`)
VALUES
('praveen', 'Like'),
('jeff', 'Comment'),
('praveen', 'Answer'),
('praveen', 'Share'),
('jeff', 'Comment'),
('bluff', 'Share'),
('jeff', 'Like')
;
查询
SELECT *, (
SELECT `fullname` FROM `users` WHERE `user` = `username`
) AS `name` FROM `actions`
+---------+---------+---------------+
| USER | ACTION | NAME |
+---------+---------+---------------+
| praveen | Like | Praveen Kumar |
| jeff | Comment | Jeff Atwood |
| praveen | Answer | Praveen Kumar |
| praveen | Share | Praveen Kumar |
| jeff | Comment | Jeff Atwood |
| bluff | Share | (null) |
| jeff | Like | Jeff Atwood |
+---------+---------+---------------+
预期输出
+---------+---------+---------------+
| USER | ACTION | NAME |
+---------+---------+---------------+
| praveen | Like | Praveen Kumar |
| jeff | Comment | Jeff Atwood |
| praveen | Answer | Praveen Kumar |
| praveen | Share | Praveen Kumar |
| jeff | Comment | Jeff Atwood |
| bluff | Share | bluff |
| jeff | Like | Jeff Atwood |
+---------+---------+---------------+
答案 0 :(得分:3)
使用IFNULL
SELECT *, IFNULL((
SELECT `fullname` FROM `users` WHERE `user` = `username`
),`user`) AS `name` FROM `actions`
修改强>
同样COALESCE
执行相同的操作
SELECT *, COALESCE((
SELECT `fullname` FROM `users` WHERE `user` = `username`
),`user`) AS `name` FROM `actions`
答案 1 :(得分:3)
您可以LEFT JOIN
使用CASE
语句,如下所示:
SELECT User, Action
,CASE WHEN Fullname IS NULL
THEN User
ELSE Fullname
END as Name
FROM actions a
LEFT JOIN users u
ON a.User = u.username;
输出
| USER | ACTION | NAME |
-------------------------------------
| praveen | Like | Praveen Kumar |
| jeff | Comment | Jeff Atwood |
| praveen | Answer | Praveen Kumar |
| praveen | Share | Praveen Kumar |
| jeff | Comment | Jeff Atwood |
| bluff | Share | bluff |
| jeff | Like | Jeff Atwood |
答案 2 :(得分:0)
由于得到了公认的答案,我在生产代码中使用了它,并且性能令人赞叹。注意mysql 1的用法(类似于sql server的SELECT TOP 1)。并注意COALESCE和CONCAT的组合用法,即,如果郊区为null,则不附加多余的逗号,因为','+ null = null,然后使用合并将成为空字符串。
SELECT
COALESCE((SELECT Customer.Name From Customer WHERE Quote.CustomerId = Customer.Id LIMIT 1), '') As CustomerName,
Description,
(CONCAT(COALESCE(DeliveryStreet, ''), COALESCE(CONCAT(', ', DeliverySuburb), ''), COALESCE(CONCAT(', ', DeliveryCity), ''), COALESCE(CONCAT(', ', DeliveryPostcode), ''))) as DeliveryAddress,
COALESCE(DATE_FORMAT(CreatedDate, '%d %b %y'), '') as QuoteCreatedDate,
COALESCE((SELECT User.Name FROM QuoteStatusHistory INNER JOIN Status ON Status.Id = QuoteStatusHistory.StatusId INNER JOIN User ON QuoteStatusHistory.UserId = User.Id WHERE QuoteStatusHistory.QuoteId = Quote.Id AND QuoteStatusHistory.StatusId = 1 ORDER BY QuoteStatusHistory.CreatedDate DESC LIMIT 1), '') as CreatedBy,
COALESCE((SELECT DATE_FORMAT(QuoteStatusHistory.CreatedDate, '%d %b %y') FROM QuoteStatusHistory WHERE QuoteStatusHistory.QuoteId = Quote.Id AND QuoteStatusHistory.StatusId = 2 ORDER BY QuoteStatusHistory.CreatedDate DESC LIMIT 1), '') as OrderDate,
COALESCE((SELECT User.Name FROM QuoteStatusHistory INNER JOIN Status ON Status.Id = QuoteStatusHistory.StatusId INNER JOIN User ON QuoteStatusHistory.UserId = User.Id WHERE QuoteStatusHistory.QuoteId = Quote.Id AND QuoteStatusHistory.StatusId = 2 ORDER BY QuoteStatusHistory.CreatedDate DESC LIMIT 1), '') as OrderedBy,
COALESCE((SELECT DATE_FORMAT(QuoteStatusHistory.CreatedDate, '%d %b %y') FROM QuoteStatusHistory WHERE QuoteStatusHistory.QuoteId = Quote.Id AND QuoteStatusHistory.StatusId IN (3, 4) ORDER BY QuoteStatusHistory.CreatedDate DESC LIMIT 1), '') as DispatchDate,
QuotePrice,
COALESCE((SELECT Status.Name FROM QuoteStatusHistory INNER JOIN Status ON Status.Id = QuoteStatusHistory.StatusId WHERE QuoteStatusHistory.QuoteId = Quote.Id ORDER BY QuoteStatusHistory.CreatedDate DESC LIMIT 1), '') as QuoteStatus
FROM Quote