2015-12-02 130 views
1

需要从下表中谁没有时间,在十一月获得这些IDS 2015年如何避免重复的列值

表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 

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

非常感谢您的任何建议。

回答

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月的时间。

0

您的查询选择不在11月份的行,然后显示它们具有的不同id_no。如果你想只检索没有在十一月发生的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) 
0

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

to_char函数我不会用于选择,因为数据库必须将此函数应用于每条记录,才能开始过滤。范围选择如BETWEEN>= AND <=通常要快得多且清晰易读。

两个选项:

1)清洁和简单的:通过id_no上组,计数站点中所有出现在2015年11月,仅返回具有计数的那些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' 
) 
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 |