【问题标题】:Conditional Sql Query条件 SQL 查询
【发布时间】:2010-02-10 10:03:05
【问题描述】:

我正在显示下表中的一个属性。现在我要做的是,在同一位置找到房产(假设我的房产位于 sec-19,匹配 sec-19,如果没有找到,则搜索整个城市),条件如下:它应该在 10 天前发布,或者如果没有在 10 天前发布,则在 30 天后的基础上获得结果。

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

现在我想从这个表中检索的是那些上市时间少于 10 天的房产的“Propertyid”和“平均价格”,如果它们都不少于 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 天前发布的。友好地重新检查并尝试解决我的问题。提前致谢。

【问题讨论】:

  • 社区维基?真的吗 ?我猜为什么对回答这个问题失去了兴趣,那肯定不是社区 wiki 的候选人。
  • 您必须在一个查询中执行此操作吗?

标签: sql database sql-server-2008


【解决方案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。

【讨论】:

  • 仍然无法正常工作...顺便说一句,这不是我的要求!!!我必须在同一位置找到房产(假设我的房产位于 sec-19,匹配 sec-19,如果没有找到,则搜索整个城市),条件是它应该发布 10几天前,或者如果没有发布 10 天前,则根据 30 天前的结果。
  • 如果您的数据类型和模式名称相同,我将彻底解决问题,您应该能够复制并通过它并让它工作。唯一使用的列名是listingtime、location、city和propertyid以及表的属性。
【解决方案2】:

您上面描述的意思是,如果过去 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))  

【讨论】:

  • 我需要从 10 天前发布的房产中计算“平均价格”,如果 10 天前没有房产,则将其视为 30 天前。像这样:从属性中选择 SUM(Price)/COUNT(PropertyId) As Average_Price where (DATEDIFF(day,listingtime,getdate())
  • 使用 SELECT AVG(Price) FROM [上述查询] 你得到一个包含一个字段的单行,因为这是多行的平均值。如果您想要结果集中的其他字段,您必须了解 GROUP BY 的工作原理。
  • 是的,我知道按标准分组的工作原理。它需要采取一些标准来对结果进行分组。但是如果要返回的字段比使用group by的地方多,因为它会返回错误。
【解决方案3】:

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

  1. 将位置传递到存储过程中并从位置匹配的属性中进行选择
  2. 将结果插入带有 propertyid、listingtime 和 avgprice 的临时表(当前为空)
  3. 选择 DATEDIFF 为 10 天的行。如果结果为 0,则选择 DATEDIFF 为 30 天的行
  4. 从临时表中选择 AVG 价格,如果有数据则过滤 10 天。将该值插入到表的每一行中

您可能想尝试更改第 1 项和第 3 项的顺序,看看哪个会产生更好的性能。

【讨论】:

    【解决方案4】:

    应该可以这样使用:

    select section, coalesce(select avg(Price) from table iq1 where Listingdate > dateadd(day,-10,getdate()) and oq.section =iq1.section, select avg(price) from table iq2 where Listingdate > dateadd(day,-30,getdate()) 和 oq.section =iq2.section,0) 作为表 oq 中按部分分组的平均价格

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

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

    希望这会有所帮助, 史蒂夫

    编辑

    这是我进行基本测试的代码。这很简单,首先会给出该部分过去 10 天的平均值,否则为该部分的最后 30 天,所有部分的最后 10 天不合格,所有部分的最后 30 天不合格.它还将分别给出 1、2、3 或 4 的平均类型。

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

    选择sectionID,
    合并 (
    (从价格 iq1 中选择 avg(Price) where Listingdate > dateadd(day,-10,getdate())
    和 > oq.sectionID = iq1.sectionID),
    (从价格 iq2 中选择 avg(price) where Listingdate > dateadd(day,-30,getdate())
    和 > oq.sectionID =iq2.sectionID),
    (select avg(Price) from prices iq1 where Listingdate > dateadd(day,-10,getdate())),
    (select avg(Price) from prices iq1 where Listingdate > dateadd(day,-30,getdate() )),
    0 ) 作为平均价格,
    CASE WHEN(从价格 iq1 中选择 > avg(Price)
    其中Listingdate > dateadd(day,-10,getdate()) 和
    oq.sectionID = iq1.sectionID) IS NOT NULL THEN 1 ELSE
    CASE WHEN(从价格 iq2 中选择 > avg(price)
    其中Listingdate > dateadd(day,-30,getdate()) 和
    oq.sectionID =iq2.sectionID) 不为 NULL THEN 2 ELSE
    CASE WHEN(从价格 iq1 中选择 > avg(Price)
    其中 Listingdate > dateadd(day,-10,getdate())) 不是 NULL THEN 3 其他
    CASE WHEN(从价格 iq1 中选择 > avg(Price)
    其中 Listingdate > dateadd(day,-30,getdate())) 不是 NULL THEN 4 其他
    5 END END END END AS AverageType 来自价格 oq
    其中 sectionID = @SectionID 按 sectionID 分组

    【讨论】:

    • 你能详细说明一下吗?我希望这次你会在你的电脑前
    • 您好 Sanju,抱歉耽搁了。我更新了我的答案,因为我无法将脚本放在评论中。
    猜你喜欢
    • 2011-07-01
    • 2021-01-16
    • 2019-07-26
    • 2015-05-01
    • 2016-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-03
    相关资源
    最近更新 更多