2011-08-22 148 views
2

我有这样的查询,以显示SQL查询问题

有2个表,我会得到翻新次数从表改造,而客户ID和名字是从表1,客户。

enter image description here

SELECT c.[Customer-ID], c.name, COUNT(*)"Number of Renovation" 
FROM CUSTOMER c, RENOVATION r 
WHERE c.[Customer-ID] = r.[Customer-ID] 
GROUP BY c.[Customer-ID], c.name 
HAVING Count(*) in 
(SELECT COUNT(*) FROM RENOVATION GROUP BY [Customer-ID]) 
ORDER BY c.[customer-id] 

,这不是为我做的查询正确的方式,任何人知道如何缩短查询?或其他方式做到这一点?尽管它仍然找到答案。顺便说一句,我正在学习SQL服务器。

+0

我想列出客户和他们有翻新的数量。我想使用子查询,但不知道如果我做正确的事情。 – Desmond

+0

Having子句与Where子句类似,只是它附加到Group By子句。由于要求中没有限制条件,因此不需要Having条款。 – deutschZuid

回答

5

OK,所以你想让客户,他们有装修 - 为什么不使用:

SELECT c.[Customer-ID], c.name, COUNT(*) AS 'Number of Renovations' 
FROM dbo.CUSTOMER c 
INNER JOIN dbo.RENOVATION r ON c.[Customer-ID] = r.[Customer-ID] 
GROUP BY c.[Customer-ID], c.name 

我不太明白你想实现你的查询HAVING COUNT(*) IN......部分的.. ....

如果你想有一个至少有一个装修的所有客户 - 试试这个:

SELECT c.[Customer-ID], c.name, COUNT(*) AS 'Number of Renovations' 
FROM dbo.CUSTOMER c 
INNER JOIN dbo.RENOVATION r ON c.[Customer-ID] = r.[Customer-ID] 
GROUP BY c.[Customer-ID], c.name 
HAVING COUNT(*) > 0 
+0

我看,那是多么短暂,可以,它的作品!谢谢Marc_s。 我会认为在我做下一步之前,HAVING子句用于查找是否有值。 – Desmond

3

HAVING条款似乎不是T o属于这里。 HAVING旨在根据聚合结果过滤出结果组。例如,你可以使用HAVING子句排除没有任何装修记录:

SELECT c.[Customer-ID], c.name, COUNT(*) AS [Number of Renovations] 
FROM dbo.CUSTOMER c 
INNER JOIN dbo.RENOVATION r ON c.[Customer-ID] = r.[Customer-ID] 
GROUP BY c.[Customer-ID], c.name 
HAVING COUNT(*) > 0 
+1

由于@marc_s在上面发布了相同的答案 - 并且代码几乎相同 - 他应该得到选票。 –

+0

感谢boris的评论,将从中吸取教训。 – Desmond

0

我不建议新手在HAVING关键字,它是essentially for legacy purposes

以下是更详细的,但可能会更容易理解,因此保持(我用的桌子CUSTOMER_RENOVATION_TALLIES一个CTE,但它可能是一个VIEW

WITH CUSTOMER_RENOVATION_TALLIES ("Customer-ID", Tally) 
    AS 
    (
     SELECT [Customer-ID], COUNT(*) AS Tally 
     FROM RENOVATION 
     GROUP 
      BY [Customer-ID] 
    ) 
SELECT c."Customer-ID", c.name, r.Tally 
    FROM CUSTOMER AS c 
     INNER JOIN CUSTOMER_RENOVATION_TALLIES AS r 
      ON c."Customer-ID" = r."Customer-ID"; 

如果要包括理货化零为客户无需装修,然后UINON这套上述结果集如

WITH CUSTOMER_RENOVATION_TALLIES ("Customer-ID", Tally) 
    AS 
    (
     SELECT [Customer-ID], COUNT(*) AS Tally 
     FROM RENOVATION 
     GROUP 
      BY [Customer-ID] 
    ) 
SELECT c."Customer-ID", c.name, r.Tally 
    FROM CUSTOMER AS c 
     INNER JOIN CUSTOMER_RENOVATION_TALLIES AS r 
      ON c."Customer-ID" = r."Customer-ID" 
UNION 
SELECT c."Customer-ID", c.name, 0 AS Tally 
    FROM CUSTOMER AS c 
WHERE NOT EXISTS (
        SELECT * 
        FROM CUSTOMER_RENOVATION_TALLIES AS r 
        WHERE c."Customer-ID" = r."Customer-ID" 
       ); 
+0

我不同意你的陈述,“它本质上是为了遗留的目的”,甚至更多与你链接到的文章说,“HAVING'的意思与WHERE完全相同,但是关于什么可以编写的规则有不同的规则它跟随它的条件以及物理先于它的'SELECT'子句。“WHERE和HAVING之间有一个非常重要的区别,它使得HAVING不仅仅适用于”遗留目的“:WHERE在应用分组之前过滤记录,'HAVING'对聚合应用过滤_after_ –

+0

事实上,他们做不同的事情需要不同的术语;如果两个标准操作符被称为“WHERE”,多少**更多**令人困惑? –

+0

@Boris Nikolaevich:它可能是你错过了主要即引用“如果只有System R团队意识到他们的语言在FROM子句中没有支持派生表的语言是关系不完整的,那么他们(在他们之后,Larry Ellison和他的Oracle将SQL带给了毫无戒心的公众)可能包括这样的支持,从而允许他们的用户...不必学习HAVING。“当然,这可能是你完全理解但持有不同的观点,这对我来说很好:) – onedaywhen

0

尝试下面的查询,

select table1.id,table1.name,renovation .mobile_no from table1,renovation where table1.id=renovation.id