我有两个表,让我们将它们命名为 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万行)。我想我正在弄乱笛卡尔产品,但我无法弄清楚在哪里和为什么。
答案 0 :(得分:2)
我想从 table1 中选择一些字段,其中日期不是 table2 中的日期
此类问题通常称为反连接。有许多方法可以解决:
NOT IN
:
SELECT *
FROM t1
WHERE THEDATE NOT IN (
SELECT FROM_UNIXTIME(THEUNIXDATE, '%d.%m.%Y') FROM t2
)
NOT EXISTS
:
SELECT *
FROM t1
WHERE NOT EXISTS(
SELECT *
FROM t2
WHERE t1.THEDATE = FROM_UNIXTIME(t2.THEUNIXDATE, '%d.%m.%Y')
)
外部联接:
SELECT *
FROM t1 LEFT JOIN t2
ON t1.THEDATE = FROM_UNIXTIME(t2.THEUNIXDATE, '%d.%m.%Y')
WHERE t2.THEUNIXDATE IS NULL
@Quassnoi在博客中介绍了这三个选项的相对性能特征,其中相关列为non-nullable和nullable。简而言之,在大多数情况下,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中的总行数。