Выполнить счетчик (*) для набора результатов по группам - PullRequest
2 голосов
/ 17 января 2009

Я пытаюсь сделать хороший оператор SQL внутри хранимой процедуры.

Я посмотрел на вопрос о количестве дней, в течение которых происходили события между двумя датами. Мой пример - заказы на продажу: за какой месяц у нас были заказы на продажу?

Предположим, эта настройка:

CREATE TABLE  `sandbox`.`orders` (
  `year` int,
  `month` int,
  `day` int,
  `desc` varchar(255) 
) 

INSERT INTO orders (year, month, day, desc)  
VALUES (2009,1,1, 'New Years Resolution 1')
      ,(2009,1,1, 'Promise lose weight')
      ,(2009,1,2, 'Bagel')
      ,(2009,1,12, 'Coffee to go')

Для этих данных результат должен быть равен 3, так как было три дня с продажей. Лучшее решение, которое я нашел, это как показано ниже.

Тем не менее, создание временной таблицы, считая, что ее отбрасывание кажется избыточным. Это должно быть возможно в одном утверждении.

Кто-нибудь, кто получил "более приятное" решение, чем я?

/ л

SELECT [Year], [Month], [Day]
INTO #Some_Days
FROM Quarter
WHERE Start >= '2009-01-01' AND [End] < '2009-01-16'
GROUP BY [Year], [Month], [Day]

SELECT count(*) from #Some_Days

Ответы [ 5 ]

8 голосов
/ 17 января 2009

Извиняюсь, если я неправильно понял вопрос, но, возможно, вы могли бы сделать что-то вроде этого, как вариант:

SELECT COUNT(*) FROM
    (SELECT DISTINCT(SomeColumn)
       FROM MyTable
      WHERE Something BETWEEN 100 AND 500
      GROUP BY SomeColumn) MyTable

... чтобы обойти создание и удаление временных таблиц?

2 голосов
/ 18 января 2009

Есть два основных варианта, которые я вижу. Один из них состоит в том, чтобы сгруппировать все в подзапрос, а затем подсчитать эти отдельные строки (ответ Кристиана Нунциато). Второе - объединить несколько полей и подсчитать различные значения этого объединенного значения.

В этом случае следующая формула объединяет три поля в одну дату и время.

DATEADD(YEAR, [Quarter].Year, DATEADD(MONTH, [Quarter].Month, DATEADD(DAY, [Quarter].DAY, 0), 0), 0)

Таким образом, COUNT (DISTINCT [формула]) даст нужный вам ответ.

SELECT
    COUNT(DISTINCT DATEADD(YEAR, [Quarter].Year, DATEADD(MONTH, [Quarter].Month, DATEADD(DAY, [Quarter].DAY, 0), 0), 0))
FROM
    Quarter
WHERE
    [Quarter].Start >= '2009-01-01'
    AND [Quarter].End < '2009-01-16'

Я обычно использую маршрут подзапроса, но в зависимости от того, что вы делаете, индексов, размера таблицы, простоты формулы и т. Д., Это может быть быстрее ...

Демс.

1 голос
/ 22 марта 2012

Вы должны использовать вложенные операторы Select. Внутренний должен содержать предложение group by, а внешний должен считать его. Я думаю, что "Кристиан Нунциато" уже помог вам.

Select Count(1) As Quantity
From
(    
    SELECT [Year], [Month], [Day]
    INTO #Some_Days
    FROM Quarter
    WHERE Start >= '2009-01-01' AND [End] < '2009-01-16'
    GROUP BY [Year], [Month], [Day]
) AS InnerResultSet
1 голос
/ 17 января 2009

Как насчет:

SELECT COUNT(DISTINCT day) FROM orders 
WHERE (year, month) = (2009, 1);

На самом деле, я не знаю, поддерживает ли TSQL сравнение кортежей, но вы поняли.

COUNT(DISTINCT expr) является стандартным SQL и должен работать везде.

0 голосов
/ 17 января 2009
SELECT [Year], [Month], [Day]
FROM Quarter
WHERE Start >= '2009-01-01' AND [End] < '2009-01-16'
GROUP BY [Year], [Month], [Day]
COMPUTE COUNT(*)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...