以下问题-http://www.sqlfiddle.com/#!9/696ed2/4
,我无法获得任何结果或正确的结果总体目标是将链接在一起的用户的所有交易列为“客户”。因此,如果John在看他的仪表板,他将看到Alice(他的客户)租了哪些书(包括书名),以及卖了哪些书(他将无法看到该书名)。>
当两个多个表联接到父表时,两个相关表的每行都设置了“活动”标志,我似乎无法仅获得活动行。
# USERS
CREATE TABLE `users` (
`id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`active` boolean DEFAULT NULL
);
INSERT INTO `users` (`id`, `name`, `active`) VALUES
(1, 'John', 1),
(2, 'Alice', 1),
(3, 'Jess', 1),
(4, 'Bob', 1);
# BOOKS
CREATE TABLE `books` (
`id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`active` boolean DEFAULT NULL
);
INSERT INTO `books` (`id`, `name`, `active`) VALUES
(1, 'On the Road', 1),
(2, 'Neuromancer', 0),
(3, 'Modern History', 1),
(4, 'Red Mars', 1);
# TRANSACTIONS
CREATE TABLE `transactions` (
`id` int(11) NOT NULL,
`user_1_id` int(11) NOT NULL,
`user_2_id` int(11) DEFAULT NULL,
`book_id` int(11) DEFAULT NULL,
`timestamp` varchar(20) DEFAULT NULL,
`type` enum('Rent', 'Sold') NOT NULL
);
INSERT INTO `transactions` (`id`, `user_1_id`, `user_2_id`, `book_id`, `timestamp`, `type`) VALUES
(1, 1, 2, 1, '1465238591', 'Rent'),
(2, 2, 1, 2, '1465238592', 'Rent'),
(3, 2, 3, 3, '1465238593', 'Rent'),
(4, 3, 4, NULL, '1465238594', 'Sold'),
(5, 2, 3, NULL, '1465238595', 'Sold'),
(6, 3, 4, NULL, '1465238596', 'Sold'),
(7, 2, 2, 4, '1465238597', 'Rent'),
(8, 1, 3, 1, '1465238598', 'Rent'),
(9, 2, 4, 2, '1465238598', 'Rent');
# RELATIONSHIPS
CREATE TABLE `relationships` (
`id` int(11) NOT NULL,
`user_1_id` int(11) DEFAULT NULL,
`user_2_id` int(11) NOT NULL,
`type` enum('Customer', 'Supplier') NOT NULL
);
INSERT INTO `relationships` (`id`, `user_1_id`, `user_2_id`, `type`) VALUES
(1, 1, 2, 'Customer'),
(2, 2, 1, 'Customer'),
(3, 2, 4, 'Customer'),
(3, 1, 4, 'Supplier'),
(3, 3, 1, 'Customer');
查询:
SELECT DISTINCT
t.id,
t.type,
t.timestamp,
u1.name as user_1_name,
u2.name as user_2_name,
b.name as book_name
FROM transactions t
LEFT JOIN relationships r ON (r.user_1_id = 1 AND r.type = 'Customer')
LEFT JOIN books b ON (b.id = t.book_id AND b.active)
LEFT JOIN users u1 ON (u1.id = t.user_1_id) # AND u1.active
LEFT JOIN users u2 ON (u2.id = t.user_2_id) # AND u2.active
WHERE (r.user_2_id = t.user_1_id OR t.user_2_id = 1 AND t.user_1_id != 1)
# AND b.active AND u1.active AND u2.active
[结果] :
| id | type | timestamp | user_1_name | user_2_name | book_name |
|----|------|------------|-------------|-------------|----------------|
| 3 | Rent | 1465238593 | Alice | Jess | Modern History |
| 2 | Rent | 1465238592 | Alice | John | (null) | <<< Should not be here
| 7 | Rent | 1465238597 | Alice | Alice | Red Mars |
| 5 | Sold | 1465238595 | Alice | Jess | (null) | <<< Correct
| 9 | Rent | 1465238598 | Alice | Bob | (null) | <<< Should not be here
在上述结果中,问题在于书籍Neuromancer的标记“ active”设置为0,因此不应出现在结果中。我曾在不同的地方放置AND b.active
,但结果总是错误的。 (请参见http://www.sqlfiddle.com/#!9/696ed2/5)
看着上面的烂摊子,我什至不确定我的方法是否有效,欢迎提出任何建议。
答案 0 :(得分:0)
正如D. Smania在评论中所提到的,您需要确保b.active
是1
或NULL
,但要根据您的LEFT JOIN
条件b.active
为1
,因此您只需要在id
上进行联接,并依靠WHERE
条件进行比较。这应该会产生您要求的结果:
SELECT DISTINCT
t.id,
t.type,
t.timestamp,
u1.name AS user_1_name,
u2.name AS user_2_name,
b.name AS book_name
FROM transactions t
LEFT JOIN relationships r ON (r.user_1_id = 1 AND r.type = 'Customer')
LEFT JOIN books b ON (b.id = t.book_id)
LEFT JOIN users u1 ON (u1.id = t.user_1_id)
LEFT JOIN users u2 ON (u2.id = t.user_2_id)
WHERE (r.user_2_id = t.user_1_id OR t.user_2_id = 1 AND t.user_1_id != 1)
AND (b.active OR b.active IS NULL)
AND u1.active AND u2.active
一个音符-在您的第一个WHERE
状态下,我不清楚您是不是故意这样:
(r.user_2_id = t.user_1_id OR (t.user_2_id = 1 AND t.user_1_id != 1))
或
((r.user_2_id = t.user_1_id OR t.user_2_id = 1) AND t.user_1_id != 1)
当您有相邻的AND
和OR
条件时,最好始终将逻辑分组明确。