返回在列中具有相同确切项的不同名称对

时间:2015-11-04 04:49:30

标签: sqlite relational-division

我想在表格中找到不同的名称对,这些名称在items列中具有相同的确切项目。例如:

CREATE TABLE t
(
    name    VARCHAR(255),
    item    VARCHAR(255)
);

INSERT INTO t VALUES("Alice", "Orange");
INSERT INTO t VALUES("Alice", "Pear");
INSERT INTO t VALUES("Alice", "Lemon");
INSERT INTO t VALUES("Bob", "Orange");
INSERT INTO t VALUES("Bob", "Pear");
INSERT INTO t VALUES("Bob", "Lemon");
INSERT INTO t VALUES("Charlie", "Pear");
INSERT INTO t VALUES("Charlie", "Lemon");

这里的答案是Alice,Bob,因为他们采用完全相同的项目。

我想用双重否定(使用NOT EXISTS / NOT IN)来做这件事,我觉得它更适合这个问题,但我无法想出任何远离功能的东西。

这有点类似this问题但是我使用SQLite所以我不能使用GROUP_CONCAT()但是我想知道如何使用NOT使用关系除法EXISTS / NOT IN。

4 个答案:

答案 0 :(得分:1)

要获取所有名称对之间的公共项目数,可以使用以下查询:

SELECT t1.name AS name1, t2.name AS name2, COUNT(*) AS cnt
FROM t AS t1
INNER JOIN t AS t2 ON t1.item = t2.item AND t1.name < t2.name
GROUP BY t1.name, t2.name

<强>输出:

name1   name2       cnt
------------------------
Alice   Bob         3
Alice   Charlie     2
Bob     Charlie     2

现在您只想过滤掉(name1, name2)对,其计数不等于name1name2的项目数。您可以使用带有相关子查询的HAVING子句来执行此操作:

SELECT t1.name AS name1, t2.name AS name2
FROM t AS t1
INNER JOIN t AS t2 ON t1.item = t2.item AND t1.name < t2.name
GROUP BY t1.name, t2.name
HAVING COUNT(*) = (SELECT COUNT(*) FROM t WHERE name = t1.name) AND 
       COUNT(*) = (SELECT COUNT(*) FROM t WHERE name = t2.name)

Demo here

答案 1 :(得分:1)

使用compound queries

SELECT t1.name, t2.name
FROM t AS t1, t AS t2
GROUP BY t1.name, t2.name
HAVING t1.name < t2.name
   AND NOT EXISTS (SELECT item FROM t WHERE name = t1.name
                   EXCEPT
                   SELECT item FROM t WHERE name = t2.name)
   AND NOT EXISTS (SELECT item FROM t WHERE name = t2.name
                   EXCEPT
                   SELECT item FROM t WHERE name = t1.name);

使用NOT IN是可能的,bit表示完全相同的机制,具有更高的复杂性:

SELECT t1.name, t2.name
FROM t AS t1, t AS t2
GROUP BY t1.name, t2.name
HAVING t1.name < t2.name
   AND NOT EXISTS (SELECT item
                   FROM t
                   WHERE name = t1.name
                     AND item NOT IN (SELECT item
                                      FROM t
                                      WHERE name = t2.name))
   AND NOT EXISTS (SELECT item
                   FROM t
                   WHERE name = t2.name
                     AND item NOT IN (SELECT item
                                      FROM t
                                      WHERE name = t1.name));

答案 2 :(得分:0)

我可能找到了解决您问题的方法。我使用MySQL进行了测试,但它没有使用GROUP_CONCAT()。它可能适用于您的SQLite数据库。我的查询用于查找已购买相同商品的人。

尝试使用此声明: place_id

https://gyazo.com/5e5e9d0ddfb33cb47439a674297108ed

答案 3 :(得分:0)

这似乎与SQLLite一起使用

    select t1.name
    from t t1
        join t t2 on t1.name <> t2.name and t1.item = t2.item 
        join (select name, count(*) as cnt from t group by name) t3 on t3.name = t1.name
        join (select name, count(*) as cnt from t group by name) t4 on t4.name = t2.name
    group by t1.name, t3.cnt, t4.cnt
    having count(*) = max(t3.cnt, t4.cnt)