如何避免重复的列值

时间:2015-12-02 08:13:15

标签: mysql oracle

需要从下表中获得那些没有时间参加2015年11月的ID

表1:

id_no        time-in 

S12      02-JUL-10 08.00.00
S12      07-OCT-10 10.00.00
S12      23-FEB-11 08.00.00
S12      01-FEB-14 09.00.00
S12      26-NOV-15 00.00.00
S68      15-MAR-06 08.00.00
S80      28-OCT-09 08.00.00
S80      07-OCT-10 10.00.00
S80      23-FEB-11 08.00.00

示例输出

id_no 
s68
s80

我不知道如何编写上面的查询。我尝试了下面的

SELECT DISTINCT ID_NO FROM TABLE1
WHERE TO_CHAR(TIME_IN, 'YYYYMM') not in('201511');

我得到输出为

id_no 
s12
s68
s80

我可以理解它需要表中的重复ids条目。 我需要避免这种情况 请帮助编写查询以获取输出作为“样本输出”。

非常感谢任何建议。

4 个答案:

答案 0 :(得分:0)

SELECT DISTINCT ID_NO FROM TABLE1 WHERE TO_CHAR(TIME_IN, 'YYYYMM') <> ('201511')
MINUS
SELECT DISTINCT ID_NO FROM TABLE1 WHERE TO_CHAR(TIME_IN, 'YYYYMM') = '201511';

以上查询将丢弃s12,因为它在2015年11月有时间。

答案 1 :(得分:0)

您的查询选择不在11月的行,然后显示他们拥有的不同id_no。如果您只想检索11月份没有出现的ID,exists运营商可以帮助您:

SELECT DISTINCT id_no
FROM   table1 t1
WHERE  NOT EXISTS (SELECT *
                   FROM   table1 t2
                   WHERE  TO_CHAR(t2.time_in, 'YYYYMM') = '201511' AND
                          t1.id_no = t2.id_no)

答案 2 :(得分:0)

您所做的DISTINCT语句是正确的,以防止重复。我个人更喜欢使用GROUP BY,但两者都是可能的。

我不会用于选择的to_char函数,因为DB必须在每个记录开始过滤之前将此函数应用于每个记录。像BETWEEN>= AND <=这样的范围选择通常更快更清晰。

两个选项:

1)简洁明了:按id_no分组,计算2015年11月所有的site-in,并仅返回那些具有0的那些。

SELECT t1.id_no
FROM table1 AS t1
GROUP BY id_no
HAVING SUM(IF(t1.time-in BETWEEN '2015-11-01'AND '2015-12-01', 1, 0)) = 0;

2)使用子查询。我可以想象MySQL会更容易成功地使用索引。 (灵感来自Mureinik's回答):

SELECT DISTINCT t1.id_no
FROM   table1 AS t1
WHERE  id_no NOT IN (
    SELECT DISTINCT id_no
    FROM   table1 AS t2
    WHERE  t2.time-in BETWEEN '2015-11-01' AND '2015-12-01'
)

答案 3 :(得分:0)

SQL Fiddle

MySQL 5.6架构设置

CREATE TABLE TABLE_NAME AS
          SELECT 'S12' as id_no, DATE '2010-06-02' AS time_in
UNION ALL SELECT 'S12', DATE '2010-10-07'
UNION ALL SELECT 'S12', DATE '2011-02-23'
UNION ALL SELECT 'S12', DATE '2014-02-01'
UNION ALL SELECT 'S12', DATE '2015-11-26'
UNION ALL SELECT 'S68', DATE '2006-03-15'
UNION ALL SELECT 'S80', DATE '2009-10-28'
UNION ALL SELECT 'S80', DATE '2010-10-07'
UNION ALL SELECT 'S80', DATE '2011-02-23';

查询1

SELECT id_no
FROM   table_name
GROUP BY id_no
HAVING COUNT( CASE WHEN DATE_FORMAT( time_in, '%Y-%m-01' ) = DATE '2015-11-01' THEN 1 END ) = 0

<强> Results

| id_no |
|-------|
|   S68 |
|   S80 |