2012-04-27 63 views
4

我有一个查询,它适用于我使用DISTINCT时。不过,我有一种感觉,我可以用一种方式重写查询,这样可以避免使用DISTINCT,这将使数据库更容易(更快速)处理查询。如何避免不同

如果重写查询没有意义,请解释一下,如果有,请查看简化查询并给我一个提示如何重新配置​​它,这样我就不会在第一个地方得到重复。

SELECT Us.user_id, COUNT( DISTINCT Or.order_id ) AS orders 
FROM users AS Us 
LEFT JOIN events AS Ev ON Ev.user_id = Us.user_id 
LEFT JOIN orders AS Or ON Or.event_id = Ev.event_id 
OR Or.user_id = Us.user_id 
GROUP BY Us.user_id 

查询的简短描述:我有一个用户,他们的事件和订单的表。有时订单有user_id列,但大部分是空的,他们必须通过事件表连接。

编辑:

这些都是简化查询我写的,第一没有明显的结果,然后包括不同。

user_id orders 
3952 263 
3953 7 
3954 2 
3955 6 
3956 1 
3957 0 
... 

user_id orders 
3952 79 
3953 7 
3954 2 
3955 6 
3956 1 
3957 0 
... 

问题固定:

SELECT COALESCE(Or.user_id, Ev.user_id) AS user, COUNT(Or.order_id) AS orders 
FROM orders AS Or 
LEFT JOIN events AS Ev ON Ev.event_id = Or.event_id 
GROUP BY COALESCE(Or.user_id, Ev.user_id) 
+0

这些ID的是独特的,有什么关系 – 2012-04-27 08:50:03

+0

在猜测,是不是'order_id' 'orders'表中唯一?在这种情况下,'DISTINCT'在这里没有任何用处。 – eggyal 2012-04-27 08:50:15

+0

order_id是主要的。然而,我已经尝试了没有它的查询,它提供了更高的数字。 – 2012-04-27 08:59:51

回答

1

您没有从用户表中获取任何内容,也没有获取事件表,因此为什么要加入它们。你的最后一个“OR”子句明确指出它有一个user_ID列。我希望您的订单表在用户ID下订单指数,那么你可以只是做

select 
     user_id, 
     count(*) as Orders 
    from 
     orders 
    group by 
     user_id 
+0

我其实确实需要事件表,但我已经意识到我可以没有用户表和组由COALESCE(Ev.user_id,Or.user_id),所以我重新组织查询而不使用用户表并且实际解决了问题。谢谢,我知道我只是在某处乱搞,我可以不用重复的东西。 – 2012-04-27 11:42:23

1

如果订单可以与多个事件,或与事件多次用户相关联,那么可能的是相同的顺序具有相同的相关联用户多次。在这种情况下,使用DISTINCT将仅为每位用户计算一次该订单,而忽略该订单将为与用户的每次关联计数一次。

如果你是在前者之后,那么你现有的查询是你最好的选择。