通过Min()SQL使用多个表、多个值

通过Min()SQL使用多个表、多个值,sql,iphone,sqlite,Sql,Iphone,Sqlite,我正在开发的应用程序中使用SQLite。 我正在尝试运行一个非常复杂的查询(对我来说很复杂!),我已经得到了我需要的基本结果,但我仍在克服最后一个障碍 我现在有这个查询,它做我需要它做的事情 SELECT SUM(activity) FROM activities WHERE activity_id IN(SELECT name_id FROM foods GROUP BY name_id HAVING SUM(points) > 20); 我需要在这个查询中添加另一个部分,但这对我

我正在开发的应用程序中使用SQLite。
我正在尝试运行一个非常复杂的查询(对我来说很复杂!),我已经得到了我需要的基本结果,但我仍在克服最后一个障碍

我现在有这个查询,它做我需要它做的事情

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);
下面的查询是我提出的,如果没有任何语法的话(lol!)。这不起作用,但我只是想展示它,以便更好地理解我正在尝试做什么

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  
有了这个ex和来自我的原始帖子(一个不起作用的帖子)的查询,我将寻找一个包含一个值的结果集..8.0

最小值(26.0-20,9.0)=6.0
最小值(29.0-20,2.0)=2.0
6.0+2.0=8.0


我希望这有帮助

同意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-根据需求澄清添加了上述查询

同意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-根据需求澄清添加了上述查询

经过多次挠头和猜测,我怀疑您想要的可能是:

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,子选择给出了您提到的其他数字!-)

经过多次的挠头和占卜,我怀疑你想要的可能是:

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,子选择给出了您提到的其他数字!-)

你能不能输入一个小的表格示例(尽可能简单)和一个小的期望结果集?好的。我编辑了我的文章,加入了一个例子。谢谢你能不能输入一个小的表格示例(尽可能简单)和一个小的期望结果集?好的。我编辑了我的文章,加入了一个例子。谢谢嘿,谢谢…当我看到你的帖子时,我已经在添加示例表了,所以我还是刚刚完成了。我将努力落实你的建议。无论如何,我编辑了我的OP,加入了一个例子,这个例子在设计查询时起作用,但实际上我需要一些不同的东西,我想这是我没有更好地解释它的错。在我要实现的应用程序中,我只关心点大于20的名称。只有在点数大于20的情况下,才能求和并减去20。我真的很感激它,因为它看起来很棒,我希望我能很好地使用sql,知道在哪里添加一个部件来实现这一点……有什么想法吗?@freddydyd-如果我理解正确,你想从foods表中筛选出所有聚合,其中SUM()小于20,对吗?您可以使用have筛选聚合后的值。它与WHERE基本相同,只是WHERE在聚合之前应用,have在聚合之后应用。我把它添加到上面的查询中,让我们知道这是否是您正在寻找的。感谢您为此付出的努力。您的查询给出了正确的最终结果…8.0,但它没有给出相同的子集结果,这也是我需要的。我不确定在我需要的查询中哪里出错了,但不管怎样,它都很有帮助……我在下面学习了更多关于sql的知识,学习了这一点和Alex的查询。我不想再浪费你的时间了,因为我最终还是使用了Alex的查询。非常感谢您的时间!!!嘿,谢谢…当我看到你的帖子时,我已经在添加示例表了,所以我还是刚刚完成了。我将努力落实你的建议。不管怎样,我编辑了我的OP,加入了一个例子,这个例子在设计查询时起了作用,但实际上我需要一些不同的东西,我想这就是