MySQL返回了巨大的结果,但不应该

时间:2014-08-10 15:19:06

标签: mysql sql date

我有两个表,让我们将它们命名为 table1 table2

Table1 以普通格式存储日期dd.mm.yyyy, table2 将日期存储为UNIX时间戳。

现在,我想从 table1 中选择一些字段,其中日期不是 table2 中的日期。我构建了这个查询:

SELECT 
    table1.field1,
    table1.field2,
    table1.field3,
    table1.THEDATE
FROM
    table1,
    table2
WHERE
    table1.THEDATE<> FROM_UNIXTIME(table2.THEUNIXDATE, '%d.%m.%Y')

为了比较这两个日期,我将UNIX时间戳转换为给出 table1 日期的格式。

我不知道转换或比较是否失败,但我得到了一个巨大的结果(上次我中止查询的行数为100万行)。我想我正在弄乱笛卡尔产品,但我无法弄清楚在哪里和为什么。

2 个答案:

答案 0 :(得分:2)

  

我想从 table1 中选择一些字段,其中日期不是 table2 中的日期

此类问题通常称为反连接。有许多方法可以解决:

  1. NOT IN

    SELECT *
    FROM   t1
    WHERE  THEDATE NOT IN (
             SELECT FROM_UNIXTIME(THEUNIXDATE, '%d.%m.%Y') FROM t2
           )
    
  2. NOT EXISTS

    SELECT *
    FROM   t1
    WHERE  NOT EXISTS(
             SELECT *
             FROM   t2
             WHERE  t1.THEDATE = FROM_UNIXTIME(t2.THEUNIXDATE, '%d.%m.%Y')
           )
    
  3. 外部联接:

    SELECT *
    FROM   t1 LEFT JOIN t2
              ON t1.THEDATE = FROM_UNIXTIME(t2.THEUNIXDATE, '%d.%m.%Y')
    WHERE  t2.THEUNIXDATE IS NULL
    
  4. @Quassnoi在博客中介绍了这三个选项的相对性能特征,其中相关列为non-nullablenullable。简而言之,在大多数情况下,MySQL将优化NOT IN(我个人认为这也是最具可读性的方法)与其他方法一样好。

    正如其他人在上述评论中所指出的那样,您目前正在使用笛卡尔积(对您没用);并且您应该使用其时态数据类型将您的时间值存储在MySQL中,例如: DATE and TIMESTAMP而不是整数。

答案 1 :(得分:0)

以下是一些要查询的问题 -

SELECT 
    table1.field1,
    table1.field2,
    table1.field3,
    table1.THEDATE
FROM
    table1
LEFT OUTER JOIN
    table2
ON
    table1.THEDATE = FROM_UNIXTIME(table2.THEUNIXDATE, '%d.%m.%Y')
WHERE
    FROM_UNIXTIME(table2.THEUNIXDATE, '%d.%m.%Y') IS NULL;

或 -

SELECT 
    table1.field1,
    table1.field2,
    table1.field3,
    table1.THEDATE
FROM
    table1
WHERE
    table1.THEDATE NOT IN (SELECT FROM_UNIXTIME(table2.THEUNIXDATE, '%d.%m.%Y') FROM table2);

对于上述两个查询,返回的行数应小于或等于table1中的总行数。