条件Sql查询

时间:2010-02-10 10:03:05

标签: sql database sql-server-2008

我正在显示下表中的属性。现在我要做的是,在相同的位置找到属性(假设我的属性位于sec-19,匹配sec-19,如果没有找到那里,那么搜索整个城市)具有以下条件:它应该在10天前发布,或者如果没有在10天后发布,则比30天后的结果更新。

我有下面提到的表格(属性):

ID|Propertyid|Userid|Projectid|..|Price|...|Listing time|... http://www.freeimagehosting.net/uploads/1e5ee2e2ad.jpg

现在我要从这个表中检索的是那些列出时间少于10天的属性的'Propertyid'和'Average Price',如果它们都不少于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)

但在这里我只得到一个Field'平均价格',这里我也没有检查过滤它是在10天前还是30天前发布的。 Knidly Recheck并尝试解决我的问题。提前致谢。

4 个答案:

答案 0 :(得分:1)

我花了一些时间在这上面,我相信我解决了你所有的担忧。我不完全确定城市或位置的数据类型所以我使用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。

答案 1 :(得分:0)

您在上面描述的内容意味着,如果过去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))  

答案 2 :(得分:0)

如果您想要一个属性ID列表,但只需要一个平均价格,那么如果您执行多个查询,生活会更简单。这听起来像使用存储过程的好例子。你可以这样做:

  1. 将位置传递到存储过程,并从位置匹配的属性中选择
  2. 将结果插入到临时表中,其中包含propertyid,listingtime和avgprice(当前为空)
  3. 选择DATEDIFF为10天的行。如果为0,则选择DATEDIFF为30天的行
  4. 从临时表中选择AVG价格,如果有数据则在10天内过滤。将该值插入表格的每一行
  5. 您可能希望更改第1项和第3项的顺序,以查看哪种效果更佳。

答案 3 :(得分:0)

应该可以使用这样的东西:

选择部分,合并(从表iq1中选择avg(Price),其中,清单&gt; dateadd(日,-10,getdate())和oq.section = iq1.section,从表格iq2中选择avg(price) &gt; dateadd(day,-30,getdate())和oq.section = iq2.section,0)作为表oq group by section的平均价格

几点说明: 抱歉,我不在我的电脑前,所以我无法证明这一点并且括号可能已经出来,但这是一般使用的想法合并到第一个标准并且提供没有记录,平均值应该返回null并使用第二个标准,如果没有,则最终为0。

另一件事是使用上面的日期添加功能来使表达式成为SARGable并且能够使用索引。

希望这有帮助, 史蒂夫

修改

这是我已经完成基本测试的代码。这很简单,并且会首先给出过去10天内该部分的平均值,如果没有,那么该部分的最后30天,所有部分的最后10天未通过,并且所有部分的最后30天都没有失败。它还将分别给出1,2,3或4的avergageType。

我提前为SQL显示的状态道歉 - 我还没有弄清楚如何很好地格式化它 - 它真的很晚了:)

  

选择sectionID,
  合并(
  (从价格iq1中选择平均价格(价格)其中,列出日期&gt; dateadd(day,-10,getdate())
  和&gt; oq.sectionID = iq1.sectionID),
  (从价格iq2中选择平均值(价格),其中,上市日期&gt; dateadd(day,-30,getdate())
  和&gt; oq.sectionID = iq2.sectionID),
  (从价格iq1中选择平均值(价格),其中列出日期&gt; dateadd(日,-10,getdate())),(从价格iq1中选择平均值&gt; dateadd(日,-30, GETDATE())),   
  0)作为平均价格,
  CASE WHEN(从价格iq1中选择&gt; avg(价格)
  其中,Listingdate&gt; dateadd(day,-10,getdate())和
  oq.sectionID = iq1.sectionID)不是1,而是1   CASE WHEN(从价格iq2中选择&gt; avg(价格)
  其中,Listingdate&gt; dateadd(day,-30,getdate())和
  oq.sectionID = iq2.sectionID)不是2,而是2   CASE WHEN(从价格iq1中选择&gt; avg(价格)
  其中,Listingdate&gt; dateadd(day,-10,getdate()))IS NOT NULL 3   ELSE
  CASE WHEN(从价格iq1中选择&gt; avg(价格)
  其中,Listingdate&gt; dateadd(day,-30,getdate()))IS NOT NULL 4   ELSE
  5 END END END END作为价格的平均类型oq
  其中sectionID = @SectionID group by sectionID