Использование нескольких таблиц, нескольких значений с помощью Min () SQL

StackOverflow https://stackoverflow.com/questions/818099

  •  03-07-2019
  •  | 
  •  

Вопрос

Я использую 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

Надеюсь, это поможет!

Это было полезно?

Решение

После долгих размышлений и гаданий, я подозреваю, что вы хотите:

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, а подвыборы дают другие упомянутые вами числа! -)

Другие советы

Согласитесь с jellomonkey - я не могу точно понять, что вы хотите, если вы не покажете больше информации. Простые определения таблиц, несколько строк примеров данных и ожидаемый вывод помогут.

Вот простой пример получения значения min из таблицы на основе диапазона, границы которого определены в двух других таблицах:

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 - добавлено добавление к вышеуказанному запросу в соответствии с разъяснениями потребностей

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top