虚拟餐桌:
id FileName DateLastSaved
1 Marium.doc 2015-01-01
2 Amna.doc 2016-01-01
3 Marium.doc 2016-01-01
我希望查询返回FileName在整个表中唯一的行。应返回特定日期范围的行。 假设日期范围仅为2016,因此不应返回第三行,因为FileName不是唯一的。
我创建的查询是:
$presentquery="SELECT * FROM InitialLog i WHERE MDid='$MDid' AND
(DateLastSaved>='$firstdate' AND DateLastSaved<='$presentdate') AND NOT
EXISTS (SELECT id FROM InitialLog i2 WHERE i2.id<i.id AND i.FileName=i2.FileName )";
(其中$ firstdate和$ presentdate是日期范围的2个日期)
查询返回准确的结果,但需要时间来执行。有没有其他方法可以重写这个查询??
(我有很多行的表)
答案 0 :(得分:0)
您可以使用LEFT JOIN
获取相同的逻辑并查找空值,即
$presentquery = "SELECT DISTINCT i.* FROM InitialLog i
LEFT JOIN InitialLog i2 ON i2.id<i.id AND i.FileName=i2.FileName
WHERE i.MDid='$MDid'
AND i.DateLastSaved>='$firstdate'
AND i.DateLastSaved<='$presentdate'
AND i2.id IS NULL";
这样您就可以进行单个连接,而不是对i
中的每个值进行子查询。
答案 1 :(得分:0)
我把这个查询放在一起,它很快就会返回结果。
Select *
FROM foo
Where (`datelastsaved` > '2015-12-31' && `datelastsaved` < '2017-01-01')
AND `filename` NOT IN (
Select `filename`
FROM foo
GROUP BY `filename`
HAVING COUNT(*) > 1);
第一部分是你的普通select语句,其中where子句用于过滤日期。
第二部分是NOT IN,其中select语句找到所有具有重复文件名的文件。
Select `filename` FROM foo GROUP BY `filename` HAVING COUNT(*) > 1)
答案 2 :(得分:0)
看起来您正在尝试获取与每个文件名首次出现相关的数据,这应该有效:
SELECT *
FROM InitialLog i
WHERE MDid='$MDid'
AND DateLastSaved>='$firstdate'
AND DateLastSaved<='$presentdate'
AND id IN (SELECT MIN(id) FROM InitialLog GROUP BY FileName)
;
或者,您可以使用相同的子查询来执行JOIN:
SELECT i.*
FROM InitialLog AS i
INNER JOIN (SELECT MIN(id) AS id
FROM InitialLog
GROUP BY FileName
) AS firsts USING (id)
WHERE i.MDid='$MDid'
AND i.DateLastSaved>='$firstdate'
AND i.DateLastSaved<='$presentdate'
;