2009-05-03 54 views
0

我在开发的应用程序中使用SQLite。
我想运行一个非常复杂的查询(对我来说很复杂!),我已经得到了我需要的基本结果,但是我陷入了最后的障碍。使用多个表,使用Min()的多个值SQL

我目前有这样的查询做什么,我需要做的......

SELECT SUM(activity) 
FROM activities 
WHERE activity_id IN(SELECT name_id FROM foods GROUP BY name_id HAVING SUM(points) > 20); 

我需要另一部分添加到该查询,但是这是它已经变得对我来说有点复杂。有三个表....日期,食物,活动,我需要找到一个结果集的总和,其中包含两个不同表中两个值之间的最小数字,只要某个语句为真。

基本上..

SELECT SUM(total) FROM (SELECT MIN(value from table1 which is determined by a value in table2, value from table3) AS total 
FROM table3 
WHERE value from table3 is contained in a result set from table1); 

下面的查询是我想出了如果没有任何语法将工作(笑!)。这不起作用,但我只是想展示它来更好地理解我想要做的事情。

SELECT SUM(activity_amount) FROM (SELECT min((SELECT SUM(points) - 20 FROM foods WHERE name_id IN(SELECT pk FROM dates WHERE weekly=1) GROUP BY name_id), activity) AS activity_amount 
FROM activities 
WHERE activity_id IN(SELECT name_id FROM foods GROUP BY name_id HAVING SUM(points) > 20)); 

的问题是在MIN() ....

SELECT SUM(points) - 20 FROM food WHERE name_id IN(SELECT pk FROM dates WHERE weekly=1) GROUP BY name_id 

这种说法产生一次以上的值,但即使我确实需要这些值来对他人的MIN()比较的第一个值,我一次只需要一个......并不是一个整体。

我怎样才能得到像上面创建的工作查询?

编辑...一些示例表更好地帮助。感谢jellomonkey和hainstech

Table#1(dates) 

CREATE TABLE dates (pk INTEGER PRIMARY KEY, date INTEGER, weekly INTEGER) 
pk date  weekly 
1 05062009 1 
2 05072009 1 
3 05082009 2 

Table #2(foods) 

CREATE TABLE foods (pk INTEGER PRIMARY KEY, food VARCHAR(64), points DOUBLE, name_id INTEGER) 
pk food points name_id 
1 food1 12.0  1 
2 food2 9.0  1 
3 food3 5.0  1 
4 food4 15.0  2 
5 food5 14.0  2 
6 food6 12.0  3 

Table#3(activities) 

CREATE TABLE activities (pk INTEGER PRIMARY KEY, activity DOUBLE, activity_id INTEGER) 
pk activity activity_id 
1  5.0   1 
2  4.0   1 
3  2.0   2 
4  4.0   3 

有了这个前和查询从我原来的职位(一个不工作),我将寻找一个包含value..8.0

MIN的结果集(26.0 -20,9.0)= 6.0
MIN(29.0-20,2.0)= 2.0
6.0 + 2.0 = 8.0

我希望这有助于!

+0

难道你键入了!一个小表格示例(尽可能简单)和一个理想的结果集? – jellomonkey 2009-05-03 22:17:03

+0

好的。我编辑我的帖子以包括一个例子。谢谢!! – freddyD 2009-05-03 23:31:47

回答

2

上面的查询多少头刮和占卜后,我怀疑你想可能是什么:

SELECT SUM(MIN(fp-20, ap)) FROM 
    (SELECT dates.pk AS fd, SUM(points) AS fp 
    FROM dates 
    JOIN foods ON name_id = fd 
    GROUP BY fd 
    HAVING fp >= 20) 
    JOIN 
    (SELECT dates.pk AS ad, SUM(activity) AS ap 
    FROM dates 
    JOIN activities ON activity_id = ad 
    GROUP BY ad) 
    ON fd = ad 

名字出现的列具有零连接自己的意思,但是,嘿,至少这确实给8.0和子选择给你提到的其他号码 - )

1

同意jellomonkey - 我不明白你想要什么,除非你显示更多的信息。简单的表格定义,几行示例数据和预期输出将有所帮助。

这里是用于获取从表中最小值基于其边界在其他两个表所限定的范围内的简单的例子:

create table t1(t1id int primary key, value int) 
create table t2(t1id int, t2id int primary key, value int) 
create table t3(t2id int, t3id int primary key, value int) 

select 
    MIN(t1.value) 
from table1 as t1 
    join table2 as t2 on t2.t1id = t1.t1id 
    join table3 as t3 on t3.t2id = t2.t2id 
where t1.value between t2.value and t3.value 

这使用t2.value和t3.value作为边界寻找MIN()的范围英寸

编辑 - 谢谢张贴示例表,这有助于吨。您可以使用一些复杂的CASE语句来比较这两个值,但我会将它们放入一个行集并进行正常的MIN聚合。这将更具可读性,并且还将允许您更容易地添加一组额外的信息,以便在需要时包含在您的MIN输入中。因此,这里是一个快速的重击在我还能做什么:

select 
    SUM(activity) 
from (
    select 
     min(activity) as activity 
     ,activity_id 
    from (
     select 
      SUM(activity) as activity, activity_id 
     from activities 
     group by activity_id 
     union all 
     select 
      SUM(points)-20 
      ,name_id 
     from foods 
     group by name_id 
     having SUM(points) > 20 
    ) as activitySum 
    where activity_id in (select pk from dates where weekly=1) 
    group by activity_id 
) as activityLesserOf 

编辑#2 - 添加具有每需要澄清

+0

嘿谢谢...我已经在中间,如果添加示例表时,当我看到您的文章,所以我刚刚完成它。我会尽力实施你的建议。 无论如何,我编辑我的OP包括一个例子 – freddyD 2009-05-03 23:30:48