我有一张看起来像这样的表:
+---------------------+----------+
| date | item |
+---------------------+----------+
| 2008-11-30 11:15:59 | Plums |
| 2012-11-08 19:42:37 | Lemons |
| 2013-01-30 18:58:07 | Apples |
| 2013-02-12 13:44:45 | Pears |
| 2014-06-08 11:46:48 | Apples |
| 2014-09-01 20:28:03 | Oranges |
+---------------------+----------+
我现在想为两种情况选择项目:
1)我想选择今年(或不同的指定年份)的所有不同项目,这些项目今年是新的,这意味着它们在前几年没有出现过。因此,此查询应该给我" Oranges"因此,2014年。
2)我还想为这个(或另一个指定的)年份选择所有不同的项目,这些项目是返回,这显然意味着它们已经出现在前几年。这个查询应该给我" Apples"因此,2014年。
为了澄清,我想将这两个查询仅用于与前几年的比较。因此,如果我将2013指定为运行此查询的年份," Apples"应该显示为新的,而不是返回。
我不一定在一个查询中需要这两件事(我怀疑它是否可能),所以两个不同的查询,每个案例一个,完全没问题。
答案 0 :(得分:2)
新项目(<{3}})如何:
SELECT DISTINCT m1.item
FROM MyTable m1
LEFT JOIN MyTable m2 ON m1.item = m2.item AND YEAR(m2.date) < 2014
WHERE YEAR(m1.date) = 2014
AND m2.date IS NULL
和(SQL Fiddle)退回项:
SELECT DISTINCT m1.item
FROM MyTable m1
INNER JOIN MyTable m2 ON m1.item = m2.item
WHERE YEAR(m1.date) = 2014
AND YEAR(m2.date) < 2014
如果您想将两个查询合并在一起(SQL Fiddle或SQL Fiddle):
SELECT DISTINCT m1.item, 'New' AS Status
FROM MyTable m1
LEFT JOIN MyTable m2 ON m1.item = m2.item AND YEAR(m2.date) < 2014
WHERE YEAR(m1.date) = 2014
AND m2.date IS NULL
UNION ALL
SELECT DISTINCT m1.item, 'Returning' AS Status
FROM MyTable m1
INNER JOIN MyTable m2 ON m1.item = m2.item
WHERE YEAR(m1.date) = 2014
AND YEAR(m2.date) < 2014
ORDER BY Status;
答案 1 :(得分:2)
1 - 此解决方案可以使用索引
SELECT DISTINCT x.item
FROM my_table x
LEFT
JOIN my_table y
ON y.item = x.item
AND y.date < x.date
WHERE x.date BETWEEN '2014-01-01' AND '2014-12-31' AND y.date IS NULL;
2 - 这也可以......
SELECT DISTINCT x.item
FROM my_table x
JOIN my_table y
ON y.item = x.item
AND y.date < x.date
WHERE x.date BETWEEN '2014-01-01' AND '2014-12-31';
2显然是一个比1更简单的问题,所以我对你按此顺序要求它们感到有些惊讶!?!?
如果你从第一个查询中删除了WHERE ... IS NULL,那么你实际上得到了你“怀疑可能”的答案,但是这两个查询的UNION将达到同样的效果。
答案 2 :(得分:1)
这将为您提供特定年份的水果,而不是其他年份的水果
SELECT t.item
FROM table t
WHERE YEAR(t.date) = 2014
AND NOT EXISTS (SELECT 1 FROM table f WHERE YEAR(f.date) <> 2014 AND f.item = t.item)
这将为您提供超过一年的
SELECT t.item
FROM table t
WHERE YEAR(t.date) = 2014
AND EXISTS (SELECT 1 FROM table f WHERE YEAR(f.date) <> 2014 AND f.item = t.item)
你可以把它们全部放在一起。
SELECT t.item as "NEW", f.item as 'RETURNING'
FROM
( SELECT t.item, @a := (COALESCE(@a, 0) + 1) as join_col
FROM test t
WHERE YEAR(t.date) = 2014
AND NOT EXISTS (SELECT 1 FROM test f WHERE YEAR(f.date) <> 2014 AND f.item = t.item)
) t
LEFT JOIN
( SELECT t.item , @b := (COALESCE(@b, 0) + 1) as join_col
FROM test t
WHERE YEAR(t.date) = 2014
AND EXISTS (SELECT 1 FROM test f WHERE YEAR(f.date) <> 2014 AND f.item = t.item)
) f ON f.join_col = t.join_col;