如何以有效的方式使用min()和max()?

时间:2012-04-26 13:05:12

标签: sql performance sqlite max min

我有一个SQL查询,我检查一个值是否在表的最大值和最小值之间。我现在实现如下:

SELECT spectrum_id, feature_table_id
FROM 'spectrum', 'feature' 
WHERE `spectrum`.msrun_msrun_id = 1
AND `feature`.msrun_msrun_id = 1
AND (SELECT min(rt) FROM `convexhull` WHERE `convexhull`.feature_feature_table_id =  `feature`.feature_table_id) <= scan_start_time 
AND scan_start_time <= (SELECT max(rt) FROM `convexhull` WHERE 'convexhull'.feature_feature_table_id = 'feature'.feature_table_id)
AND (SELECT min(mz) FROM `convexhull` WHERE `convexhull`.feature_feature_table_id = `feature`.feature_table_id) <= base_peak_mz 
AND base_peak_mz <= (SELECT max(mz) FROM `convexhull` WHERE `convexhull`.feature_feature_table_id = `feature`feature_table_id)

运行速度非常慢,因为每次运行此查询时我都会从convexhull中选择4次,所以我尝试使用内部联接来改进它:

SELECT spectrum_id, feature_table_id 
FROM 'spectrum', 'feature'
INNER JOIN `convexhull` ON `convexhull`.feature_feature_table_id = `feature`.feature_table_id
WHERE `spectrum`.msrun_msrun_id = ? "+ 
AND `feature`.msrun_msrun_id = ? "+
AND min(`convexhull`.rt) <= scan_start_time "+
AND scan_start_time <= max(`convexhull`.rt) "+
AND min(`convexhull`.mz) <= base_peak_mz "+
AND base_peak_mz <= max(`convexhull`.mz)", spectrumFeature_InputValues)

但是,min()和max()语句只能在select语句之后使用。如何让第一个查询更有效率,这样我就可以获得min和max rt和mz而无需进行4次查询?

1 个答案:

答案 0 :(得分:6)

编辑:再多花几分钟再看一遍并意识到所有数据来自那一张桌子,所以这样的东西应该有效

SELECT 
    spectrum_id
    ,feature_table_id
FROM 
    spectrum AS s
    INNER JOIN feature AS f
        on f.msrun_msrun_id = s.msrun_msrun_id
    INNER JOIN (select 
         feature_feature_table_id
         ,min(rt) AS rtMin
        ,max(rt) AS rtMax
        ,min(mz) AS mzMin
        ,max(mz) as mzMax
     FROM 
        convexhull
     GROUP BY 
         feature_feature_table_id
     ) AS t
     ON t.feature_feature_table_id = f.feature_table_id
WHERE
    s.msrun_msrun_id = 1
    AND s.scan_start_time >= t.rtMin
    AND s.scan_start_time <= t.rtMax
    AND base_peak_mz >= t.mxMin
    AND base_peak_mz <= t.mzMax

我认为您想要通过feature_feature_table_id从凸包表和组中进行选择,以获得该分组中的最小和最大rt。

然后你可以用括号中的select来命名它(如t)并加入它。

希望这能让你上路..如果不在这里创建示例模式:http://sqlfiddle.com/

并输入您的查询,我可以修改它。

作为旁注,我想你想在特定领域加入这些表,而不是从两者中选择where子句比较:

SELECT spectrum_id, feature_table_id
FROM 'spectrum', 'feature' 
WHERE `spectrum`.msrun_msrun_id = 1
AND `feature`.msrun_msrun_id = 1

SELECT 
    spectrum_id
    ,feature_table_id
FROM 
    spectrum AS s
    INNER JOIN feature AS f
        on f.msrun_msrun_id = s.msrun_msrun_id
WHERE
    s.msrun_msrun_id = 1

如果我有问题,请告诉我。