我们有这些实体/表格 -
字段为uuid的用户。
带有字段userId的钱包,映射到用户的uuid。
用于在逻辑块下对优惠券(将发给用户)进行分组的货币。
可以发给用户的优惠券,其中userId列再次映射到用户的uuid。优惠券还有currencyId列。
我们到目前为止使用此查询对每种货币取得用户余额(使用虚拟手机号码1111111111) -
SELECT u.uuid as cuuid,u.mobile,u.email,SUM(IF(c.amount IS NULL,0,c.amount)) amountIssued,
w.balance availableAmount ,w.expiredBalance expiredAmount,
w.exhaustedBalance exhaustedAmount,w.currencyId,cy.currencyName
FROM users u
LEFT JOIN coupon c ON u.uuid = c.userId
LEFT JOIN wallet w ON w.userId = c.userId AND w.currencyId = c.currencyId
LEFT JOIN currency cy ON w.currencyId = cy.id
WHERE u.mobile = "1111111111"
and (c.merchantId = "3" or c.merchantId = -1)
GROUP BY c.currencyId;
但是,上述查询仅返回那些映射到已发出非零优惠券的货币的钱包。
现在,我们还需要显示没有发行优惠券的钱包作为非零余额钱包。我目前正在尝试进行额外的查询以获取所有与已发行优惠券无关的钱包,并将结果与现有查询的结果联系起来。但我无法解决where条件,这就是为什么我得到null输出 -
SELECT u.uuid as cuuid,u.mobile,u.email, (w.balance+w.expiredBalance+w.exhaustedBalance) as amountIssued,
w.balance availableAmount ,w.expiredBalance expiredAmount,
w.exhaustedBalance exhaustedAmount,w.currencyId,cy.currencyName
FROM users u
LEFT JOIN coupon c ON u.uuid = c.userId
LEFT JOIN wallet w ON w.userId = c.userId AND w.currencyId = c.currencyId
LEFT JOIN currency cy ON w.currencyId = cy.id
WHERE u.mobile = "1111111111"
and (c.merchantId = "3" or c.merchantId = -1)
and c.id is null
GROUP BY c.currencyId;
我期待钱包兑换货币5的结果会被退回。
Db架构和测试数据
以下是涉及的数据库模式和一些测试数据,现有查询返回一行(按预期方式),我正在尝试第二个查询返回另一个钱包行 -
CREATE TABLE `users` (
`uuid` varchar(600) DEFAULT NULL,
`mobile` varchar(60) DEFAULT NULL,
`email` varchar(300) DEFAULT NULL,
`addedon` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`updatedon` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `coupon` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userId` varchar(200) DEFAULT NULL,
`currencyId` int(11) NOT NULL,
`amount` decimal(15,2) DEFAULT '0.00',
`couponStatus` char(1) NOT NULL DEFAULT 'I',
`issueRef` varchar(100) DEFAULT NULL,
`merchantId` int(11) DEFAULT NULL,
`validFrom` timestamp NULL DEFAULT NULL,
`validTo` timestamp NULL DEFAULT NULL,
`message` varchar(256) DEFAULT NULL,
`addedon` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updatedon` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `userIdIdx` (`userId`)
) ENGINE=InnoDB AUTO_INCREMENT=10455 DEFAULT CHARSET=utf8;
CREATE TABLE `currency` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`currencyCode` varchar(30) DEFAULT NULL,
`merchantId` int(11) NOT NULL DEFAULT '0',
`currency` varchar(30) NOT NULL DEFAULT 'INR',
`currencyName` varchar(100) NOT NULL,
`validFrom` timestamp NULL DEFAULT NULL,
`validTo` timestamp NULL DEFAULT NULL,
`addedon` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updatedon` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `merchantIdIdx` (`merchantId`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;
CREATE TABLE `wallet` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`userId` varchar(200) NOT NULL DEFAULT '',
`balance` decimal(15,2) NOT NULL DEFAULT '0.00',
`expiredBalance` decimal(15,2) NOT NULL DEFAULT '0.00',
`exhaustedBalance` decimal(15,2) NOT NULL DEFAULT '0.00',
`currencyId` int(11) NOT NULL,
`addedon` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updatedon` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`Id`),
KEY `userIdIdx` (`userId`),
KEY `currencyIdIdx` (`currencyId`)
) ENGINE=InnoDB AUTO_INCREMENT=8901 DEFAULT CHARSET=latin1;
插入查询
INSERT INTO `users` (`uuid`, `mobile`, `email`, `addedon`, `updatedon`) VALUES ('9146748363211993410', '1111111111', '1111111111@test.com', '2018-06-08 16:15:29', '2018-06-08 16:15:29');
INSERT INTO `coupon` (`id`, `userId`, `currencyId`, `amount`, `couponStatus`, `issueRef`, `merchantId`, `validFrom`, `validTo`, `message`, `addedon`, `updatedon`) VALUES (10454, '9146748363211993410', 6, 2.00, 'I', 'certificate upgrade again 543', 3, '2018-04-19 00:00:00', '2018-07-19 23:59:59', 'priority 2 coupon', '2018-06-12 19:21:44', '2018-06-12 19:21:44');
INSERT INTO `currency` (`id`, `currencyCode`, `merchantId`, `currency`, `currencyName`, `validFrom`, `validTo`, `addedon`, `updatedon`) VALUES (5, NULL, 3, 'INR', 'new currency', '2016-01-06 18:56:46', '2019-02-12 11:14:23', '2017-10-05 10:38:08', '2018-02-16 13:09:20');
INSERT INTO `currency` (`id`, `currencyCode`, `merchantId`, `currency`, `currencyName`, `validFrom`, `validTo`, `addedon`, `updatedon`) VALUES (6, NULL, 3, 'INR', 'new currency 2', '2016-01-06 18:56:46', '2019-02-12 11:14:23', '2017-10-05 10:38:08', '2018-02-16 13:09:20');
INSERT INTO `wallet` (`Id`, `userId`, `balance`, `expiredBalance`, `exhaustedBalance`, `currencyId`, `addedon`, `updatedon`) VALUES (8899, '9146748363211993410', 2.00, 0.00, 0.00, 6, '2018-06-12 19:21:44', '2018-06-12 19:21:44');
INSERT INTO `wallet` (`Id`, `userId`, `balance`, `expiredBalance`, `exhaustedBalance`, `currencyId`, `addedon`, `updatedon`) VALUES (8900, '9146748363211993410', 0.00, 0.00, 0.00, 5, '2018-06-12 19:21:46', '2018-06-12 19:21:46');
更新
根据@ Barmer的评论,更改了连接子句但仍然得到相同的结果 -
SELECT u.uuid as cuuid,u.mobile,u.email, (w.balance+w.expiredBalance+w.exhaustedBalance) as amountIssued,
w.balance availableAmount ,w.expiredBalance expiredAmount,
w.exhaustedBalance exhaustedAmount,w.currencyId,cy.currencyName
FROM users u
LEFT JOIN coupon c ON u.uuid = c.userId and c.id is null
LEFT JOIN wallet w ON w.userId = c.userId AND w.currencyId = c.currencyId
LEFT JOIN currency cy ON w.currencyId = cy.id
WHERE u.mobile = "1111111111"
and (c.merchantId = "3" or c.merchantId = -1)
GROUP BY c.currencyId;
更新2
根据@Indent的建议,尝试LEFT JOIN coupon c ON u.uuid = c.userId and (c.merchantId = 3 or c.merchantId = -1)
来过滤"优惠券"在加入之前,但这似乎也不起作用。如果我在连接中添加条件c.id is null
条件,我会在结果集中得到一个空钱包行 -
SELECT w.Id, u.uuid AS cuuid,u.mobile,u.email, (w.balance+w.expiredBalance+w.exhaustedBalance) AS amountIssued,
w.balance availableAmount,w.expiredBalance expiredAmount,
w.exhaustedBalance exhaustedAmount,w.currencyId,cy.currencyName
FROM users u
LEFT JOIN coupon c ON u.uuid = c.userId AND (c.merchantId = "3" OR c.merchantId = -1) and c.id is null
LEFT JOIN wallet w ON w.userId = c.userId AND w.currencyId = c.currencyId
LEFT JOIN currency cy ON w.currencyId = cy.id
WHERE u.mobile = "1111111111"
GROUP BY w.Id;
结果 -
"Id" "cuuid" "mobile" "email" "amountIssued" "availableAmount" "expiredAmount" "exhaustedAmount" "currencyId" "currencyName"
\N "9146748363211993410" "1111111111" "1111111111@test.com" \N \N \N \N \N \N
此外,尝试了以下简单查询 -
SELECT *
FROM wallet w, users u, coupon c
WHERE u.mobile = "1111111111" AND u.uuid="9146748363211993410"
AND w.userId = u.uuid AND c.currencyId = w.currencyId;
它返回钱包和优惠券的所有组合,货币ID = 5和6.还返回属于这些货币ID下的其他用户的钱包。我无法仅过滤掉属于该用户的钱包。这是否指向这里的根本错误?
我觉得这个问题与此处标记的问题不重复。其他人可以评论吗?
更新3
添加了sql fiddle问题。