在SQLite中,我有一个像这样(简化)创建的表:
CREATE TABLE [entries] (
[id] INTEGER NOT NULL PRIMARY KEY,
[local] VARCHAR,
[remote] VARCHAR,
[value] INTEGER
);
INSERT INTO entries (local, remote, value) VALUES ("a", "b", 1);
INSERT INTO entries (local, remote, value) VALUES ("b", "a", -1);
INSERT INTO entries (local, remote, value) VALUES ("b", "a", -1);
INSERT INTO entries (local, remote, value) VALUES ("a", "d", 2);
INSERT INTO entries (local, remote, value) VALUES ("a", "d", 2);
INSERT INTO entries (local, remote, value) VALUES ("d", "a", -2);
现在我要列出彼此匹配的组合。将本地列作为本地银行帐户,将远程作为远程银行帐户。每当从本地到远程进行交易时,值 x ,并且存在一个匹配的交易,其收到的值 x 但是作为负值(与第一个找到的相关),我希望得到SQLite的输出。
我目前的做法是这样的:
sqlite3 -header demo.db \
"SELECT * FROM
(SELECT * FROM entries) AS q1,
(SELECT * FROM entries) AS q2
WHERE q1.local = q2.remote AND
q1.remote = q2.local AND
q1.value = (q2.value * -1)"
但是这会回来:
id|local|remote|value|id|local|remote|value
1|a|b|1|2|b|a|-1
1|a|b|1|3|b|a|-1
2|b|a|-1|1|a|b|1
3|b|a|-1|1|a|b|1
4|a|d|2|6|d|a|-2
5|a|d|2|6|d|a|-2
6|d|a|-2|4|a|d|2
6|d|a|-2|5|a|d|2
我想要的结果是:
id|local|remote|value|id|local|remote|value
1|a|b|1|2|b|a|-1
4|a|d|2|6|d|a|-2
不应显示没有匹配伙伴的行 - 每行只能匹配最多一个其他事务。我尝试使用 GROUP BY ,但这不适用于 q1.id 和 q2.id 作为参数。
答案 0 :(得分:2)
由于可能有多个行具有相同的local / remote / value值, 必须计算每个此类集合中行的等级,以便正确配对行。
使用除sqlite之外的其他数据库(使用行编号基元,CTE等)更容易,但在sqlite中可以获得正确的结果:
SELECT t1.id, t1.local, t1.remote, t1.value,
t2.id, t2.local, t2.remote, t2.value FROM
(SELECT q1.*, count(q1b.id) AS rank
FROM entries q1 LEFT JOIN entries q1b
ON q1.local = q1b.local AND q1.remote = q1b.remote
AND q1.value = q1b.value AND q1.id >= q1b.id
GROUP BY q1.id) AS t1,
(SELECT q2.*, count(q2b.id) AS rank
FROM entries q2 LEFT JOIN entries q2b
ON q2.local = q2b.local AND q2.remote = q2b.remote
AND q2.value = q2b.value AND q2.id >= q2b.id
GROUP BY q2.id) AS t2
WHERE t1.local = t2.remote AND t1.remote = t2.local
AND t1.value = - t2.value
AND t1.id < t2.id AND t1.rank = t2.rank
答案 1 :(得分:0)
SELECT *
FROM (SELECT MIN(id) AS id, local, remote, value
FROM entries
GROUP BY local, remote, value
) AS e1,
(SELECT MIN(id) AS id, local, remote, value
FROM entries
GROUP BY local, remote, value
) AS e2
WHERE e1.local = e2.remote
AND e1.remote = e2.local
AND e1.value = -e2.value
AND e1.id < e2.id