2011-07-19 162 views
0

我有一个表MYTABLE。 这包含顾客和地点。嵌套组SQL语句

我可以使用什么Sql语句来找出客户有多于一个地点 ,并且只能显示多于一个地点的客户?一个位置可以用于几个不同的客户。

这不起作用:这只能表明Occurances

SELECT CU _NO, LOC_NO, COUNT(LOC_NO) AS NUMBEROCC 
FROM MYTABLE 
GROUP BY LOC_NO 
HAVING (COUNT(LOC_NO)>1) 

表具有相同的客户超过一排的(抱歉,这是很重要的)

回答

1
SELECT m.CU_NO 
    , m.LOC_NO 
    , grp.NUMBEROCC 
FROM MYTABLE AS m 
    JOIN 
    (SELECT CU_NO 
      , COUNT(DISTINCT LOC_NO) AS NUMBEROCC 
     FROM MYTABLE 
     GROUP BY CU_NO 
     HAVING COUNT(DISTINCT LOC_NO) > 1 
    ) AS grp 
    ON grp.CU_NO = m.CU_NO 
ORDER BY m.CU_NO 
+0

谢谢Ypercube和Petar – icecurtain

2

的数量,您需要包括所有GROUP BY子句中的SELECT子句的非聚合字段,因此必须删除LOC字段和组CU_NO

SELECT CU_NO, COUNT(LOC_NO) AS NUMBEROCC 
FROM MYTABLE 
GROUP BY CU_NO 
HAVING (COUNT(LOC_NO)>1) 
1

,如果你想获得的所有客户的所有位置与一个以上的位置,您应该使用一个窗口函数:

SELECT t.CU_NO, t.LOC_NO, t.NUMBEROCC 
FROM (
    SELECT CU_NO, LOC_NO, COUNT(LOC_NO) OVER (PARTITION BY CU_NO) AS NUMBEROCC 
    FROM MYTABLE 
) AS t 
WHERE t.NUMBEROCC > 1 

如果你不关心的所有位置,但只是客户ID,那么你可以通过子句中使用单群:

SELECT CU_NO 
FROM MYTABLE 
GROUP BY CU_NO 
HAVING COUNT(DISTINCT LOC_NO) > 1 

但您CU_NO想组这两种情况下,不LOC_NO!


窗口函数的SQL Server实现还没有(还)!COUNT(DISTINCT x) OVER(PARTITION BY x)。所以,这会引发错误:

SELECT t.CU_NO, t.LOC_NO, t.NUMBEROCC 
FROM (
    SELECT CU_NO, LOC_NO 
     , COUNT(DISTINCT LOC_NO) OVER (PARTITION BY CU_NO) AS NUMBEROCC 
    FROM MYTABLE 
) AS t 
WHERE t.NUMBEROCC > 1 

解决方法是使用DENSE_RANK() OVER()MAX() OVER()有一个额外的查询级别:

SELECT x.CU_NO, x.LOC_NO, x.NUMBEROCC 
FROM (
    SELECT t.CU_NO, t.LOC_NO 
     , MAX(DR) OVER(PARTITION BY CU_NO) AS NUMBEROCC 
    FROM (
     SELECT CU_NO, LOC_NO 
      , DENSE_RANK() OVER (PARTITION BY CU_NO ORDER BY LOC_NO) AS DR 
     FROM MYTABLE 
    ) AS t 
) AS x 
WHERE x.NUMBEROCC > 1 
+0

问题的第一条语句显示CU_NO_ LOC_NO其次总数所有拥有该位置的客户。第二个显示只有一个位置的顾客。它是我的错,因为桌子不止一次包含同一个客户(我简化了,但是这造成了混淆) – icecurtain

+0

你确定...不可能。如果他拥有多个位置,可以不止一次地拥有同一个客户。 –

+0

我已将聚合修改为COUNT(DISTINCT LOC_NO)'。这样,即使你有重复行(相同的位置相同的custome两次)它将是正确的 –