Условный запрос SQL - PullRequest
       7

Условный запрос SQL

5 голосов
/ 10 февраля 2010

Я показываю свойство из следующей таблицы, приведенной ниже.Теперь, что мне нужно сделать, это найти недвижимость в том же месте (предположим, что моя собственность находится в секунде 19, сопоставить с секундой 19 и, если ни один из них не найден там, тогда искать весь город) со следующим условием, чтоон должен быть отправлен 10 дней назад, или если ни один не был отправлен 10 дней назад, то результат будет получен на основе 30 дней назад.

У меня есть следующая таблица (Свойства), упомянутая ниже:

ID|Propertyid|Userid|Projectid|..|Price|...|Listing time|...

Теперь, что я хочу получить из этой таблицы, это 'Propertyid' и 'Средняя цена' тех свойств, время листинга которых составляет менее 10 дней, если ни один из них не меньшечем через 10 дней, затем верните результат менее чем за 30 дней.

Может кто-нибудь помочь мне решить эту проблему.Заранее спасибо.

Или просто Любое тело может ответить мне без совпадения Местоположения.

Мне нужно рассчитать «Среднюю цену» по свойствам, опубликованным 10 дней назад, если нет размещенной собственности10 дней назад, тогда примите это как 30 дней назад.Примерно так:

Select AVG(Price) As Average_Price from Properties where (DATEDIFF(day,listingtime,getdate())<30 or DATEDIFF(day,listingtime,getdate())<10)

Но здесь я получаю только одно поле «Средняя цена», и здесь также не ставлю отметку, чтобы отфильтровать, было ли оно опубликовано 10 дней назад или 30 дней назад.Осторожно перепроверьте и попытайтесь решить мою проблему.Заранее спасибо.

Ответы [ 4 ]

1 голос
/ 15 февраля 2010

Я потратил некоторое время на это, и я думаю, что решил все ваши проблемы. Я не был полностью уверен в типах данных города или местоположения, поэтому я использовал varchar (100). Это должно решить все ваши проблемы. Пожалуйста, прокомментируйте, если есть ситуация, которую вы описали, которая не решает.

   CREATE PROCEDURE [dbo].[GetRecentlyListedProperties]
(@location varchar(100), @city varchar(100),@propertyID int)
As
Begin
DECLARE @numberOfDays int,
        @propertyCount int, 
        @IsLocation bit -- looking for a location and not a city    
SET @Propertycount = 0
SET @numberOfDays= 10 
-- CHECK TO SEE IF THERE ARE LISTINGS IN THE LAST 10 DAYS IN THE SAME LOCATION
SELECT  @PropertyCount = 
 Count(*) FROM properties where location = @location and DATEDIFF(day,listingtime,GETDATE()) < @numberOFDays
 and PropertyID != @propertyID
If(@PropertyCount = 0)
Begin
-- CHECK TO SEE IF THERE ARE LISTINGS IN THE LAST 10 DAYS IN THE SAME CITY
SELECT  @PropertyCount = Count(*) from properties where city = @city 
        AND DATEDIFF(day,listingtime,GETDATE()) < @numberOFDays
        AND PropertyID != @propertyID   
    IF(@PropertyCount = 0 )
    BEGIN
    SET @NumberOfDays = 30
    -- CHECK TO SEE IF THERE ARE LISTINGS IN THE LAST 30 DAYS IN THE SAME LOCATION
    SELECT  @PropertyCount = COUNT(*) from properties where location = @location 
            AND DATEDIFF(day,listingtime,GETDATE()) < @numberOFDays
            AND PropertyID != @propertyID
        IF(@PropertyCount = 0 )
        BEGIN
        -- CHECK TO SEE IF THERE ARE LISTINGS IN THE LAST 30 DAYS IN THE SAME CITY
        SELECT @PropertyCount = Count(*) from properties where city = @city 
                AND DATEDIFF(day,listingtime,GETDATE()) < @numberOFDays
                AND PropertyID != @propertyID
        END
        ELSE
        SET @IsLocation = 1 --There are properties in the same location in the last 30 days
    END
    ELSE
    SET @IsLocation  = 0 -- There are properties listed int he city in the last 10 days
End
Else
SET @IsLocation = 1
-- This is where the appropriate results are returned. 
IF(@IsLocation = 1)
Begin
SELECT * ,(SELECT AVG(PRICE) as AveragePrice
       FROM PROPERTIES 
       WHERE DATEDIFF(day,listingtime,GETDATE()) < @numberOFDays
         AND Location = @Location
         AND PropertyID != @propertyID)
FROM Properties 
WHERE DATEDIFF(day,listingtime,GETDATE()) < @numberOFDays
      AND Location = @Location
      AND PropertyID != @propertyID
End
ElSE
SELECT * ,(SELECT AVG(PRICE) as AveragePrice
      FROM PROPERTIES 
          WHERE DATEDIFF(day,listingtime,GETDATE()) < @numberOFDays
          AND City = @City
          AND PropertyID != @propertyID)
FROM Properties 
WHERE DATEDIFF(day,listingtime,GETDATE()) < @numberOFDays
      AND City = @City 
      AND PropertyID != @propertyID
End

Возможно, вам придется изменить некоторые типы данных для внешних ключей для местоположения и города, поскольку я использовал их в качестве varchars.

0 голосов
/ 13 февраля 2010

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

  1. передать местоположение в хранимую процедуру и выбрать из свойств, где местоположение соответствует
  2. вставить результаты во временную таблицу с помощью propertyid, listtime и avgprice (в настоящее время пусто)
  3. выберите строки с DATEDIFF 10 дней. если 0 результатов, выберите строки с DATEDIFF 30 дней
  4. выберите цену AVG из временной таблицы, фильтруя по 10 дням, если есть данные. вставить это значение в каждую строку таблицы

Вы можете поиграть с изменением порядка пунктов 1 и 3, чтобы увидеть, какие из них дают лучшую производительность.

0 голосов
/ 15 февраля 2010

Должно быть возможно использовать что-то вроде этого:

выберите раздел, объедините (выберите значение avg (цена) из таблицы iq1, где Listingdate> dateadd (день, -10, getdate ()) и oq.section = iq1.section, выберите значение avg (цена) из таблицы iq2, где Listingdate> dateadd (день, -30, getdate ()) и oq.section = iq2.section, 0) как средняя цена из таблицы oq сгруппировать по разделам

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

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

Надеюсь, это поможет, Стив

EDIT

Вот код, на котором я провел базовое тестирование. Это просто и даст вам сначала среднее значение для этого раздела за последние 10 дней, в противном случае, за последние 30 дней для раздела, если не за последние 10 дней для всех разделов и если не за последние 30 дней для всех разделов , Это также даст avergageType 1,2,3 или 4 соответственно.

Я заранее прошу прощения за состояние отображения SQL - мне еще предстоит решить, как правильно отформатировать его - и это действительно поздно:)

выберите sectionID,
объединение (
(выберите avg (Price) из цен iq1, где Listingdate> dateadd (день, -10, getdate ())
и> oq.sectionID = iq1.sectionID),
(выберите avg (цена) из цен iq2, где Listingdate> dateadd (день, -30, getdate ())
и> oq.sectionID = iq2.sectionID),
(выберите avg (Цена) из цен iq1, где Listingdate> dateadd (день, -10, getdate ())),
(выберите avg (Цена) из цен iq1, где Listingdate> dateadd (день, -30, getdate ( ))),
0) как средняя цена,
СЛУЧАЙ КОГДА (выберите> avg (цена) из цен iq1
где Listingdate> dateadd (день, -10, getdate ()) и
oq.sectionID = iq1.sectionID) НЕЛЬЗЯ ТОЛЬКО 1, Иначе
СЛУЧАЙ КОГДА (выберите> avg (цена) из цен iq2
где Listingdate> dateadd (день, -30, getdate ()) и
oq.sectionID = iq2.sectionID) НЕЛЬЗЯ ПОТОМ 2, В противном случае
СЛУЧАЙ КОГДА (выберите> avg (цена) из цен iq1
где Listingdate> dateadd (день, -10, getdate ())) не равен 3 ELSE
СЛУЧАЙ КОГДА (выберите> avg (цена) из цен iq1
где Listingdate> dateadd (день, -30, getdate ())) не равен NULL THEN 4 ELSE
5 END END END END AS AverageType от цен oq
где sectionID = @SectionID группа по sectionID

0 голосов
/ 10 февраля 2010

То, что вы описали выше, означает, что если в последние 10 дней было 1 свойство, то вы хотите перечислить это единственное. Попробуйте это: (Я использую P.age для простоты.)

SELECT * FROM properties P  
WHERE  
-- 10 days old records, if any:  
(((select count(1) from properties p1 where p1.age > 10) > 0) AND (P.age > 10))  
OR  
-- 30 days old records, if zero 10-day-old records found:  
(((select count(1) from properties p1 where p1.age > 10) = 0) AND (P.age > 30))  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...