1

我想得到所有data不在's > 6id中的 1-3id

为简单起见,我使用 id,但实际上我使用的是时间戳。

CREATE TABLE test (
  id bigint(20) NOT NULL AUTO_INCREMENT,
  data varchar(3) NOT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

INSERT INTO test (id, data) VALUES
(1, 'abc'),
(2, 'def'),
(3, 'ghi'),
(4, 'jkl'),
(5, 'mno'),
(6, 'pqr'),
(7, 'def'),
(8, 'vxw'),
(9, 'yz');

我试过的几十个查询中的一个。

SELECT
  t1.data t1_data,
  t2.data t2_data
FROM test t1
JOIN test t2
  ON t2.id BETWEEN 1 AND 3
    AND t1.id > 6
    AND t1.data <> t2.data

所以我想得到这个结果:

+----------+
|   data   |
+----------+
|   abc    |
|   ghi    |
+----------+
4

4 回答 4

1
SELECT t1.data AS t1_data
FROM test t1
WHERE t1.id BETWEEN 1 AND 3
AND NOT EXISTS(
  SELECT *
  FROM test t2 
  WHERE t2.data = t1.data
  AND  t2.id > 6
  );
于 2013-11-05T01:10:25.440 回答
1

这是 set-within-sets 子查询的示例。我喜欢使用带有having子句的聚合来处理这些,因为这是最通用的方法。在你的情况下:

select t1.data 
from test t1
group by t.data
having sum(id between 1 and 3) > 0 and
       sum(id > 6) = 0;

子句中的条件having计算满足每个条件的行数。第一个表示至少有一行(对于给定data的 )id介于 1 和 3 之间。第二个表示没有id大于 6 的行。

于 2013-11-05T01:22:59.710 回答
0

您可以使用一个NOT EXISTS子句:

SELECT DISTINCT t1.data
FROM test t1
WHERE t1.id BETWEEN 1 AND 3
AND NOT EXISTS
(
    SELECT 1
    FROM test t2
    WHERE t2.data = t1.data
    AND t2.id > 6
);

我在DISTINCT这里使用是因为我假设例如有一个与 相同的dataid=2和与 相同的data值是可能的id=3。根据需要将其删除。

于 2013-11-05T01:10:32.320 回答
0

有几种方法可以做到这一点(可能在性能方面,外连接可能是最好的)但从概念上讲是这样的:

SELECT t1.data
  FROM test t1
 WHERE t1.id < 4 
   AND t1.data NOT IN
   (SELECT t2.data
      FROM test t2
     WHERE t2.id > 6)

外部联接版本如下所示:

SELECT t1.data
  FROM test t1 LEFT OUTER JOIN test t2
    ON t1.data = t2.data and t1.id < 4 and t2.id > 6
 WHERE t2.id IS NULL
于 2013-11-05T01:16:03.293 回答