我有两个表,我想从评论表中选择作者为usr1
的所有行,并将其连接到threadid和tid列匹配的posts表,但使用MIN(positionID)
。< / p>
这是我的评论表:
cid tID author
1 | 1 | usr1 |
2 | 2 | usr2 |
3 | 3 | usr1 |
4 | 3 | usr1 |
帖子表:
id threadID rating positionID
1 | 1 | 99.99 | 1
2 | 1 | 150.00 | 2
3 | 2 | 33.10 | 1
4 | 2 | 10.00 | 2
5 | 3 | 16.00 | 1
6 | 3 | 45.00 | 2
7 | 3 | 75.00 | 3
预期结果:
cid tID author rating
1 | 1 | usr1 | 99.99
3 | 3 | usr1 | 16.00
4 | 3 | usr1 | 16.00
我在一些阅读后尝试了几个不同的查询,如下面的这个,但我在几行中得到NULL:
SELECT * FROM Reviews AS R
LEFT JOIN (SELECT * from posts GROUP BY positionID) AS P on P.threadID=R.tID
WHERE c.author_name='usr1'
也许左连接不是我需要的?
答案 0 :(得分:1)
左连接不适合在这里使用。如果要从一个表中获取所有行,并且在匹配时仅从另一个表中获取行,则使用外部联接。在这里看来,您只想获得两个表中都存在相应行的行。
你可以从写这个开始,得到你想要的行:
SELECT r.*
FROM reviews r
JOIN posts p ON p.threadid = r.tid
WHERE r.author = 'usr1';
至于获得最低位置 - 如果它从1开始,它可能总是1,所以你可以过滤它。这应该让你有这个问题:
SELECT r.cid, r.tid, r.author, p.rating
FROM reviews r
JOIN posts p ON p.threadid = r.tid
WHERE r.author = 'usr1' AND p.positionid = 1;
但是,如果你想获得最低位置ID,我会做以下事情,虽然这看起来有点棘手但可能有更好的方法:
获取组中的第一项是一个小技巧。在这种情况下,您需要threadid组中最早的positionid:
SELECT *
FROM posts p
WHERE(
SELECT COUNT(*)
FROM posts pt
WHERE pt.threadid = p.threadid AND pt.positionid <= p.positionid
) <= 1;
您可以使用该子查询加入评论表,如下所示:
SELECT r.cid, r.tid, r.author, t.rating
FROM reviews r
JOIN(SELECT *
FROM posts p
WHERE(
SELECT COUNT(*)
FROM posts pt
WHERE pt.threadid = p.threadid AND pt.positionid <= p.positionid
) <= 1) t
ON t.threadid = r.tid AND r.author = 'usr1';
这可以在SQL Fiddle中使用,但我建议先在整个数据集上进行测试。
注意以上内容与您的结果集略有不同,因为我使用了您的想法并删除了一个positionID为1的行,以确保使用下一行。它按预期工作。
答案 1 :(得分:0)
DROP TABLE IF EXISTS posts;
CREATE TABLE posts(
id INT NOT NULL AUTO_INCREMENT,
threadID INT NOT NULL,
rating DECIMAL(5,2) NOT NULL,
positionID INT NOT NULL,
PRIMARY KEY(id));
INSERT INTO posts(threadid, rating, positionid) VALUES
(1, 99.99, 1),
(1, 150.00, 2),
(2, 33.10, 1),
(2, 10.00, 2),
(3, 45.00, 2),
(3, 75.00, 3);
DROP TABLE IF EXISTS reviews;
CREATE TABLE reviews(
cid INT NOT NULL AUTO_INCREMENT,
tid INT NOT NULL,
author VARCHAR(10) NOT NULL,
PRIMARY KEY(cid));
INSERT INTO reviews(tid, author) VALUES
(1, 'usr1'),
(2, 'usr2'),
(3, 'usr1'),
(3, 'usr1');
SELECT cid,tid,author,rating
FROM posts p
JOIN
( SELECT threadid,MIN(positionid) min_positionid FROM posts GROUP BY threadid) x
ON x.threadid = p.threadid
AND x.min_positionid = p.positionid
JOIN reviews r ON r.tid = p.threadid
WHERE author = 'usr1'
;
+-----+-----+--------+--------+
| cid | tid | author | rating |
+-----+-----+--------+--------+
| 1 | 1 | usr1 | 99.99 |
| 3 | 3 | usr1 | 45.00 |
| 4 | 3 | usr1 | 45.00 |
+-----+-----+--------+--------+