重写用户计数的计数的SQL

时间:2012-06-02 22:24:20

标签: sql performance join count

我有两张桌子Cargo and Offer。我只想列出所有货物以及有特定用户提供的有效优惠的数量。 表结构如下:

货物 - 表
CargoId
CargoTime
..

优惠 - 表
OFFERID
CargoId
用户ID
OfferStatu
..

在此系统中,用户可以为货物提供多个报价,但最新报价将被视为对特定用户有效。因此,如果OfferStatu为1,那么这指的是特定用户的先前报价。

我按如下方式编写了SQL假设:

SELECT cargo.CargoId,cargo.CargoTime,COUNT(offer.OfferId) 
FROM cargo INNER join offer on offer.CargoId=cargo.CargoId
WHERE cargo.CargoId in
(
    select c.CargoId from cargo as c inner  join offer as o 
    on o.CargoId=c.CargoId
    WHERE o.UserId=12  
)
and offer.OfferStatu<>1
GROUP BY cargo.CargoId

但是这个查询在大约1秒内执行,这对我来说太过分了。我知道有一种更有效的写作方式,但我现在正在努力。

1 个答案:

答案 0 :(得分:2)

从您的问题中判断一下有点困难,但我认为您正在寻找与货物相关的所有优惠的计数,即使它们不是由特定用户制作的正在寻找。 (例如,如果货物有来自用户10和12的报价,则计数将为2,即使我们只搜索用户12)

试试这个:

SELECT
  cargo.CargoId,
  cargo.CargoTime,
  COUNT(offer.OfferId) AS OfferCount
FROM
    cargo
  INNER JOIN
    offer
  ON
    offer.CargoId = cargo.CargoId
WHERE
  offer.OfferStatu <> 1
GROUP BY
  cargo.CargoId,
  cargo.CargoTime
HAVING
  SUM(CASE offer.UserId WHEN 12 THEN 1 ELSE 0 END) <> 0;

SQL Fiddle

至于这是否会比您目前的效率更高,这通常取决于您的具体情况,您必须进行测试以确保。人们会期望这个查询更有效率,因为只有一个货物和提供表的访问,但它确实取决于。