2014-12-15 2 views
1

У меня есть таблица, которая определяется следующим образом:TSQL эффективность запроса

CREATE TABLE [dbo].[ListingStats](
    [ListingStatID] [int] IDENTITY(1,1) NOT NULL, 
    [StatTypeID] [int] NOT NULL, 
    [CreatedDate] [date] NOT NULL, 
    [ListingID] [int] NOT NULL, 
    CONSTRAINT [PK_ListingStats] PRIMARY KEY CLUSTERED 
(
[ListingStatID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
     ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

Я пытаюсь получить 4 итоговые значения для каждого типа (listingStatTypeID) на сегодняшний день, последние 7 дней, последние 30 дней, и все время ,

Я не уверен, какой самый эффективный запрос будет. Прямо сейчас у меня есть следующее, что я могу повторить для каждого TYPE, но это будет большой запрос, и будет много вызовов.

declare @listingID int 
set @listingID = 209722 
--today 
select count(1) from ListingStats where listingid = @listingid and CreatedDate = getdate() 
--last 7 days 
select count(1) from ListingStats where listingid = @listingid and CreatedDate > getdate()-7 
--last 30 days 
select count(1) from ListingStats where listingid = @listingid and CreatedDate > getdate()-30 
--all time 
select count(1) from ListingStats where listingid = @listingid 

Я всегда вызываю это для одного списка за раз, предоставляя идентификатор листинга. Если бы кто-нибудь мог указать направление, я был бы признателен. Должен ли я создать какое-то представление?

Ожидаемые результаты

-Type------Today-----7Days---30Days---Ever 
    1   44  50  500 5000 
    2   22  40  90  1000 
    3   55  55  555 5555 

ответ

2

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

SELECT SUM(CASE WHEN CreatedDate = getdate() THEN 1 ELSE 0 END) AS v_today, 
     SUM(CASE WHEN CreatedDate > getdate()-7 THEN 1 ELSE 0 END) AS v_week, 
     SUM(CASE WHEN CreatedDate > getdate()-30 THEN 1 ELSE 0 END) AS v_month, 
     COUNT(*) AS v_alltime 
    FROM ListingStats 
WHERE listingid = @listingid 

Для все Аукциона идентификаторов , то

SELECT ListingID, 
     SUM(CASE WHEN CreatedDate = getdate() THEN 1 ELSE 0 END) AS v_today, 
     SUM(CASE WHEN CreatedDate > getdate()-7 THEN 1 ELSE 0 END) AS v_week, 
     SUM(CASE WHEN CreatedDate > getdate()-30 THEN 1 ELSE 0 END) AS v_month, 
     COUNT(*) AS v_alltime 
    FROM ListingStats 
GROUP BY ListingID 

Если вы хотите получить резюме для каждого StatTypeID (в пределах ListingID), затем:

SELECT ListingID, 
     StatTypeID, 
     SUM(CASE WHEN CreatedDate = getdate() THEN 1 ELSE 0 END) AS v_today, 
     SUM(CASE WHEN CreatedDate > getdate()-7 THEN 1 ELSE 0 END) AS v_week, 
     SUM(CASE WHEN CreatedDate > getdate()-30 THEN 1 ELSE 0 END) AS v_month, 
     COUNT(*) AS v_alltime 
    FROM ListingStats 
GROUP BY ListingID, StatTypeID 

Если вы хотите резюме от StatTypeID по всем ListingIDs, то:

SELECT StatTypeID, 
     SUM(CASE WHEN CreatedDate = getdate() THEN 1 ELSE 0 END) AS v_today, 
     SUM(CASE WHEN CreatedDate > getdate()-7 THEN 1 ELSE 0 END) AS v_week, 
     SUM(CASE WHEN CreatedDate > getdate()-30 THEN 1 ELSE 0 END) AS v_month, 
     COUNT(*) AS v_alltime 
    FROM ListingStats 
GROUP BY StatTypeID 

Судя из раздела «Ожидаемые результаты», которые были добавлены, этот последний запрос находится ближе всего к тому, что вам нужно. И, судя по комментариям, если вы хотите резюме от StatTypeID для конкретного ListingID, то:

SELECT StatTypeID, 
     SUM(CASE WHEN CreatedDate = getdate() THEN 1 ELSE 0 END) AS v_today, 
     SUM(CASE WHEN CreatedDate > getdate()-7 THEN 1 ELSE 0 END) AS v_week, 
     SUM(CASE WHEN CreatedDate > getdate()-30 THEN 1 ELSE 0 END) AS v_month, 
     COUNT(*) AS v_alltime 
    FROM ListingStats 
WHERE ListingID = @listingid 
GROUP BY StatTypeID 

Если есть проблемы с вашими вызовами функции getdate() (как предложено Gordon Linoff в его answer), вам также необходимо исправить их.

+0

Я думаю, что ваш последний запрос - это то, что я ищу, но изменение конца на where listingid = @listingid GROUP BY StatTypeID и удаление листинга из select, а также фиксация даты, когда Gordon указал – Zoinky

+0

. Есть ли какая-либо польза в посылке этого запроса в представлении?он будет называться по требованию (пользователь должен нажать кнопку, чтобы довести статистику) – Zoinky

+0

Если вы все еще ищете информацию для одного значения листинга, то да, измените последний запрос с помощью 'WHERE ListingID = @ listingid' , –

1

Вы можете сделать это с помощью условной агрегации. Это помещает значения в четыре колонки:

select sum(case when CreatedDate = cast(getdate() as date) then 1 else 0 end) as today, 
     sum(case when CreatedDate > cast(getdate() - 7 as date) then 1 else 0 end) as lastweek, 
     sum(case when CreatedDate > cast(getdate() - 30 as date) then 1 else 0 end) as last30, 
     count(*) as ever 
from ListingStats 
where listingid = @listingid; 

Обратите внимание, что getdate() возвращает datetime с временной составляющей (несмотря на название), так что этот запрос отбрасывает значение даты (удаление компонента времени).

Чтобы получить это для всех Аукциона идентификаторов:

select sum(case when CreatedDate = cast(getdate() as date) then 1 else 0 end) as today, 
     sum(case when CreatedDate > cast(getdate() - 7 as date) then 1 else 0 end) as lastweek, 
     sum(case when CreatedDate > cast(getdate() - 30 as date) then 1 else 0 end) as last30, 
     count(*) as ever 
from ListingStats 
group by listingid; 
+0

Спасибо, теперь я должен сделать это для типа охвата, должен ли я вызывать один и тот же запрос для каждого типа или есть более эффективный способ их разделить, я обновлю оригинальное сообщение о том, как мне нужно, чтобы результат выглядел как – Zoinky

+0

, добавив, что столбец в 'group by ' будет выполнять вашу работу. –

Смежные вопросы