【问题标题】:Using Multiple Tables, Multiple Values with Min() SQL使用 Min() SQL 使用多个表、多个值
【发布时间】:2009-05-03 21:53:39
【问题描述】:

我正在开发的应用程序中使用 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);

下面的查询是我想出的,如果没有任何语法(哈哈!)。这不起作用,但我只是想展示它以更好地理解我正在尝试做的事情。

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

MIN(26.0-20, 9.0) = 6.0
MIN(29.0-20, 2.0) = 2.0
6.0 + 2.0 = 8.0

我希望这会有所帮助!

【问题讨论】:

  • 您能输入一个小表格示例(尽可能简单)和一些想要的结果集吗?
  • 好的。我编辑了我的帖子以包含一个示例。谢谢!!

标签: sql iphone sqlite


【解决方案1】:

经过一番摸索和猜测后,我怀疑您想要的可能是:

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

【讨论】:

  • 亚历克斯,非常感谢!!这太棒了。我要问你的唯一另一件事是这个查询考虑了所有 pk 的日期。我如何只检索“每周= 1”的日期的pk?我猜你在哪里有“...FROM dates JOIN foods ON name_id ....”,我可以做到“....FROM dates WHERE week=1 JOIN foods ON name_id ....”。这行得通吗?
  • Alex,我正在考虑更多,但我认为这不会像我建议的那样起作用,对吧?我认为这会导致 JOIN 出错?
  • 在语法上,WHERE dates.weekly = 1 位于 JOIN 之后,您在两个内部 SELECT 中都需要它。
【解决方案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 - 根据需要说明将 HAVING 添加到上述查询中

【讨论】:

  • 嘿,谢谢...如果在我看到您的帖子时添加示例表,我已经在中间,所以我还是完成了它。我将尝试实施您的建议。无论如何,我编辑了我的 OP 以包含一个示例
  • 这在设计查询时起作用,但实际上我需要一些不同的东西,我想那是我没有更好地解释它的错。在我要实现这个的应用程序中,我只关心点数大于 20 的 name_id。取 sum(points) 并减去 20 只会在点数大于 20 的情况下进行。我真的很感激,因为这个看起来很棒,我希望我对 sql 足够好,知道在哪里添加一个部件来实现这一点......有什么想法吗?
  • @freddyD - 如果我理解正确,您想从食品表中过滤掉 SUM() 小于 20 的所有聚合,对吗?您可以使用 HAVING 过滤聚合后的值。它与 WHERE 基本相同,只是 WHERE 应用在聚合之前,而 HAVING 应用在聚合之后。我将它添加到上面的查询中,如果这就是您要查找的内容,请告诉我们。
  • 感谢您为此付出的努力。您的查询给出了正确的最终结果...8.0,但它没有给出相同的子集结果,这也是我需要的。我不确定查询在我需要的地方出了什么问题,但无论如何它都会有所帮助......我已经了解了更多关于 sql 研究这个和下面 Alex 的查询的知识。我不想再浪费您的时间了,因为无论如何我最终还是使用了 Alex 的查询。非常感谢您的宝贵时间!!!
猜你喜欢
  • 2012-10-29
  • 2013-02-16
  • 2013-10-16
  • 2014-08-04
  • 2015-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多