删除已关联“time_worked”记录的SQL结果

时间:2015-07-10 18:19:19

标签: mysql sql

编辑:我在底部添加了一个更明确的例子。

这是查询,架构和结果(如果需要,可以在SQLfiddle上查看):

SQL Fiddle

MySQL 5.6架构设置

CREATE TABLE IF NOT EXISTS `transactions` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `effective_sn` int(11) DEFAULT NULL,
  `serial_num` int(11) DEFAULT NULL,
  `actor` varchar(100) DEFAULT NULL,
  `type` varchar(20) DEFAULT NULL,
  `trans_data` text,
  `trans_date` int(11) DEFAULT NULL,
  `trans_prev` text,
  `content` text,
  PRIMARY KEY (`id`),
  KEY `effective_sn` (`effective_sn`),
  KEY `serial_num` (`serial_num`),
  KEY `type_index` (`type`),
  KEY `trans_date_index` (`trans_date`),
  FULLTEXT KEY `content` (`content`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1093579 ;

INSERT INTO `transactions` (`id`, `effective_sn`, `serial_num`, `actor`, `type`, `trans_data`, `trans_date`, `trans_prev`, `content`) VALUES
(1091622, 100628, 100628, 'jhvisser', 'comment', '', 1435864188, NULL, 'some comment'),
(1091749, 100628, 100628, 'jhvisser', 'comment', '', 1435926407, NULL, 'some comment'),
(1092012, 100628, 100628, 'jhvisser', 'comment', '', 1436189497, NULL, 'some comment'),
(1092085, 100628, 100628, 'jhvisser', 'comment', '', 1436199139, NULL, 'some comment'),
(1092162, 100628, 100628, 'jhvisser', 'comment', '', 1436205996, NULL, 'some comment'),
(1092240, 100628, 100628, 'jhvisser', 'comment', '', 1436211675, NULL, 'some comment'),
(1092252, 100628, 100628, 'jhvisser', 'comment', '', 1436213410, NULL, 'some comment'),
(1092288, 100628, 100628, 'jhvisser', 'comment', '', 1436217645, NULL, 'some comment'),
(1092376, 100628, 100628, 'jhvisser', 'comment', '', 1436277006, NULL, 'some comment'),
(1093530, 100628, 100628, 'jhvisser', 'time_worked', '60', 1436551662, NULL, NULL),
(1093531, 100628, 100628, 'jhvisser', 'comment', '', 1436551662, NULL, 'some comment');

查询1

SELECT *  FROM `transactions` WHERE `serial_num` = 100628 and (type='comment' or type='time_worked')

Results

|      id | effective_sn | serial_num |    actor |        type | trans_data | trans_date | trans_prev |      content |
|---------|--------------|------------|----------|-------------|------------|------------|------------|--------------|
| 1091622 |       100628 |     100628 | jhvisser |     comment |            | 1435864188 |     (null) | some comment |
| 1091749 |       100628 |     100628 | jhvisser |     comment |            | 1435926407 |     (null) | some comment |
| 1092012 |       100628 |     100628 | jhvisser |     comment |            | 1436189497 |     (null) | some comment |
| 1092085 |       100628 |     100628 | jhvisser |     comment |            | 1436199139 |     (null) | some comment |
| 1092162 |       100628 |     100628 | jhvisser |     comment |            | 1436205996 |     (null) | some comment |
| 1092240 |       100628 |     100628 | jhvisser |     comment |            | 1436211675 |     (null) | some comment |
| 1092252 |       100628 |     100628 | jhvisser |     comment |            | 1436213410 |     (null) | some comment |
| 1092288 |       100628 |     100628 | jhvisser |     comment |            | 1436217645 |     (null) | some comment |
| 1092376 |       100628 |     100628 | jhvisser |     comment |            | 1436277006 |     (null) | some comment |
| 1093530 |       100628 |     100628 | jhvisser | time_worked |         60 | 1436551662 |     (null) |       (null) |
| 1093531 |       100628 |     100628 | jhvisser |     comment |            | 1436551662 |     (null) | some comment |

在此查询中,我显示time_worked类型,以便您可以看到我所指的内容。如果在创建评论记录之前或之后的5分钟内创建了comment类型记录,我不希望time_worked出现在结果中。

这可能令人困惑,但这个想法本身很简单,所以我将用一个示例案例来解释它。我正在使用时间跟踪应用程序。很多时候人们对这些项目发表评论并忘记记录工作时间。这个想法是我想找到没有记录时间的评论。人们可以意识到他们忘记并在几分钟后添加工作时间,这就是为什么我说它可以在5分钟之前或之后创建。

查看上图中的结果,将会有2个结果不应该存在,而这些是最后两个,因为在评论发布时添加了时间。

是否可以在SQL中执行类似的操作?

编辑:

输入:类似上面的SQL查询。 输出:我想修改现有的查询,以摆脱具有关联“time_worked”类型的“注释”类型。当我提到类型时,我指的是实际的列type,其中包含数据commenttime_worked。基本上,如果time_worked类型和comment具有相同的trans_date(unix时间),则它们不应出现在结果中。

所以在示例数据中我给出的最后两行不会显示。

2 个答案:

答案 0 :(得分:1)

您正在做的是查找同一表中的关联记录不存在某种类型的记录。为此,请使用LEFT self JOIN:

SELECT comments.*, DATE_SUB(FROM_UNIXTIME(comments.
            trans_date), INTERVAL 5 MINUTE), 
    timeworked.id
FROM transactions AS comments
LEFT JOIN transactions AS timeworked ON comments.
    serial_num = timeworked.serial_num
    AND FROM_UNIXTIME(comments.trans_date) BETWEEN 
            DATE_SUB(FROM_UNIXTIME(timeworked.
                    trans_date), INTERVAL 5 MINUTE)
        AND DATE_ADD(FROM_UNIXTIME(timeworked.
                    trans_date), INTERVAL 5 MINUTE)
    AND timeworked.type = 'time_worked'
WHERE comments.type = 'comment'
    AND timeworked.id IS NULL

答案 1 :(得分:0)

我确信在SQL中可以做到这一点,这是一种始终有效的方法(注意 - 可能有更好的方法可以做到,但这总是有效)。既然你的问题有点含糊我不能具体,但我希望你能用它来获得好结果。

SELECT * 
FROM
(
  SELECT base.*,
         CASE WHEN (criteria for exclusion is true) THEN 1 ELSE 0 END AS flag
  FROM
  (
     -- this is where you select your base data from your original table
     SELECT * 
     FROM table
  ) AS base
) as filter
WHERE FLAG != 1

如果您要求条件需要检查原始数据中的另一行,那么您将加入到最里面的select语句中。