Минимальная сумма

delit
Дата: 25.11.2009 03:16:32
Есть запрос, который считает сумма. Выглядить так:
SELECT Sum(Контракты.[СуммаКонт(руб)]) AS [Sum-СуммаКонт(руб)], Товары.КодТовара, Товары.[Наименование товара], Sum(Контракты.КолПоКонт) AS [Sum-КолПоКонт], Count(Контракты.НомКонт) AS [Count-НомКонт]
FROM Товары INNER JOIN Контракты ON Товары.КодТовара = Контракты.Код_Товара
GROUP BY Товары.КодТовара, Товары.[Наименование товара]

Вопрос - возможно ли одним запросом получить минимальное значение Sum(Контракты.[СуммаКонт(руб)])
delit
Дата: 25.11.2009 03:18:42
Хм.. тут же нашел интересное решение
SELECT TOP 1  Sum(Контракты.[СуммаКонт(руб)]) AS [Sum-СуммаКонт(руб)], Товары.КодТовара, Товары.[Наименование товара], Sum(Контракты.КолПоКонт) AS [Sum-КолПоКонт], Count(Контракты.НомКонт) AS [Count-НомКонт]
FROM Товары INNER JOIN Контракты ON Товары.КодТовара = Контракты.Код_Товара
GROUP BY Товары.КодТовара, Товары.[Наименование товара]
ORDER BY Sum(Контракты.[СуммаКонт(руб)]);

А другим способом это сделать можно?
mds_world
Дата: 25.11.2009 10:06:57
delit
А другим способом это сделать можно?

Зависит от того, что вы хотите получить на выходе. Если одно число - Min(Sum(Контракты.[СуммаКонт(руб)])), то просто заверните первый вариант запроса в еще один селект
Select Min([Sum-СуммаКонт(руб)]) From ТекстЗапроса
Если же требуется одновременно выдавать и другие сведения, то этого будет мало и применяются более сложные конструкции.
delit
Дата: 26.11.2009 13:09:22
Хочется вывести еще какие то поля. А можно пример этой сложной конструкции?
qwrqwr
Дата: 26.11.2009 13:18:41
delit
Есть запрос, который считает сумма. Выглядить так:
SELECT Sum(Контракты.[СуммаКонт(руб)]) AS [Sum-СуммаКонт(руб)], Товары.КодТовара, Товары.[Наименование товара], Sum(Контракты.КолПоКонт) AS [Sum-КолПоКонт], Count(Контракты.НомКонт) AS [Count-НомКонт]
FROM Товары INNER JOIN Контракты ON Товары.КодТовара = Контракты.Код_Товара
GROUP BY Товары.КодТовара, Товары.[Наименование товара]
Вопрос - возможно ли одним запросом получить минимальное значение Sum(Контракты.[СуммаКонт(руб)])

SELECT TOP 1 Sum(K.[СуммаКонт(руб)]) AS Sum_руб, T.КодТовара, T.[Наименование товара],
       Sum(K.КолПоКонт) AS Sum_Кол, Count(K.НомКонт) AS Count_Конт
  FROM Товары T INNER JOIN Контракты K ON T.КодТовара = K.Код_Товара
 GROUP BY T.КодТовара, T.[Наименование товара]
 ORDER BY Sum_руб;
?
delit
Дата: 26.11.2009 20:57:39
Не, ну это решение пришло мне в голову сразу после того как я нажал кновку "Опубликовать". На мой взгляд, оно не интресно и не очень красиво.
qwrqwr
Дата: 26.11.2009 23:45:12
delit
На мой взгляд, оно не интресно и не очень красиво.
А-аа, так Вы эстет и ищете красоты и интереса? :)

Покаюсь - прочел 1е сообщение без второго - и запостил повторно вариант с топ 1 :((

Ну вот, выбирайте в соответствии с эстетическими предпочтениями:
SELECT Sum(K.[СуммаКонт(руб)]) AS Sum_руб, T.КодТовара, T.[Наименование товара], Sum(K.КолПоКонт) AS Sum_Кол, Count(K.НомКонт) AS Count_Конт
  FROM Товары AS T INNER JOIN Контракты AS K ON T.КодТовара=K.Код_Товара
 GROUP BY T.КодТовара, T.[Наименование товара]
HAVING Sum(K.[СуммаКонт(руб)]) =(SELECT Min(Q.Sum_руб) AS minsum
                                   FROM (SELECT Sum(K.[СуммаКонт(руб)]) AS Sum_руб
                                           FROM Товары AS T INNER JOIN Контракты AS K ON T.КодТовара = K.Код_Товара
                                          GROUP BY T.КодТовара, T.[Наименование товара]) AS Q
                                );
SELECT Sum(K.[СуммаКонт(руб)]) AS Sum_руб, T.КодТовара, T.[Наименование товара], Sum(K.КолПоКонт) AS Sum_Кол, Count(K.НомКонт) AS Count_Конт
  FROM Товары AS T INNER JOIN Контракты AS K ON T.КодТовара=K.Код_Товара
 GROUP BY T.КодТовара, T.[Наименование товара]
HAVING Sum(K.[СуммаКонт(руб)]) <= All (SELECT Sum(K.[СуммаКонт(руб)]) AS Sum_руб
                                         FROM Товары AS T INNER JOIN Контракты AS K ON T.КодТовара = K.Код_Товара
                                        GROUP BY T.КодТовара, T.[Наименование товара]);
SELECT * FROM (
SELECT Sum(K.[СуммаКонт(руб)]) AS Sum_руб, T.КодТовара, T.[Наименование товара], Sum(K.КолПоКонт) AS Sum_Кол, Count(K.НомКонт) AS Count_Конт
  FROM Товары AS T INNER JOIN Контракты AS K ON T.КодТовара=K.Код_Товара
 GROUP BY T.КодТовара, T.[Наименование товара]
              ) AS Q1,
(SELECT Min(Q.Sum_руб) AS minsum FROM (SELECT Sum(K.[СуммаКонт(руб)]) AS Sum_руб
                                         FROM Товары AS T INNER JOIN Контракты AS K ON T.КодТовара = K.Код_Товара
                                        GROUP BY T.КодТовара, T.[Наименование товара]) AS Q
) AS Q2
 WHERE Q1.Sum_руб=Q2.minsum;
Хотя лично мне больше нравится с Top 1 - но на вкус и цвет...
отакота
Дата: 27.11.2009 10:02:26
qwrqwr
Хотя лично мне больше нравится с Top 1 - но на вкус и цвет...
Так у всех этих вышеприведенных вариантов есть одно радикальное отличие от варианта с Top 1: поскольку для отбора используется условие по сумме, то все эти запросы могут вернуть несколько записей - если это условие выполнится для нескольких записей - т.е. при суммировании окажется несколько товаров с одинаковой суммой. В то время как вариант с Top 1 всегда вернет только одну запись - независимо от этого.

Поэтому тут даже не вопрос эстетики, тут вопрос уточнения ТЗ - а что, собственно, нужно получить в результате, если повторится эта минимальная сумма для разных товаров? Если нужно получить ВСЕ эти товары - то подойдет любой из этих трех запросов. Если же в этом случае на выходе нужна строго одна запись - то использовать Top 1.
qwrqwr
Дата: 27.11.2009 11:59:22
отакота
Если нужно получить ВСЕ эти товары - то подойдет любой из этих трех запросов. Если же в этом случае на выходе нужна строго одна запись - то использовать Top 1.
Несогласный я :)
Запросы тут все эквивалентные. SELECT TOP 1 ..... ORDER BY Условие в Акцесс действует как with ties в mssql - т.е. выдаст все записи с минимальным Условие
А вот SELECT TOP 1 без ордер бай - выдаст действительно одну запись (недетерминированную :)
Наверное, комбинируя в подзапросах select top X с/без сортировки - в Акцессе из-за этих особенностей можно соорудить что-то особенное (и плохочитабельное) - сам не пробовал...
отакота
Дата: 27.11.2009 12:12:23
qwrqwr
отакота
Если нужно получить ВСЕ эти товары - то подойдет любой из этих трех запросов. Если же в этом случае на выходе нужна строго одна запись - то использовать Top 1.
Несогласный я :)
А вот SELECT TOP 1 без ордер бай - выдаст действительно одну запись
тогда в чем же несогласие? я про этот самый "SELECT TOP 1 без ордер бай" и говорил. я же сравнивал три последних приведенных запроса и тот вариант, что был в этой ветке выше приведен c TOP 1 - он ведь без order by.