2

我有

 select CustID,

case permission
When 'read' then 'X'
end as 'Read',

case permission
when 'write' then 'X'
end as 'Write',

case permission
when 'own' then 'X'
end as 'Own',

case permission
when ‘destroy’ then ‘X’
end as ‘Destroy’

from rights

group by custID, permission

我只想为每个 custID 写一行。相反,我得到:

CustID    |  Read | Write |  Own | Destroy

208345482     X     NULL    NULL   NULL| 
208345482    NULL   NULL     X     NULL|
208345482    NULL   NULL    NULL      X|
208345482    NULL    X      NUL    NULL|
8093657522   NULL   NULL    NULL     X|
8093657522   NULL   NULL     X    NULL|

我试图按别名子查询分组,但无济于事。任何帮助将不胜感激。

4

2 回答 2

3

您不能在其中使用别名,GROUP BY因为它在应用别名之前已被解析。您可以使用别名的唯一位置是在ORDER BY子句中,因为它是唯一SELECT在定义别名之后解析的子句。

典型的解决方法是重复GROUP BY子句中的表达式:

SELECT x = CASE ... END, SUM(something)
  FROM dbo.somewhere
  GROUP BY CASE ... END;

或使用 CTE:

;WITH src AS
(
  SELECT x = CASE ... END, something
    FROM dbo.somewhere
)
SELECT x, SUM(something)
  FROM src
  GROUP BY x;

或使用子查询:

SELECT x, SUM(something)
  FROM
  (
    SELECT x = CASE ... END, something
      FROM dbo.somewhere
  ) AS src
  GROUP BY x;

这些都应该进行类似的优化,但您应该测试您的特定场景以确定。

在你的情况下,你可以这样写:

SELECT CustID,
  [Read]    = MAX(CASE permission WHEN 'read'    THEN 'X' END),
  [Write]   = MAX(CASE permission WHEN 'write'   THEN 'X' END),
  [Own]     = MAX(CASE permission WHEN 'own'     THEN 'X' END),
  [Destroy] = MAX(CASE permission WHEN 'destroy' THEN 'X' END)
FROM dbo.rights
GROUP BY custID;

或者像这样:

SELECT CustID,
  MAX([Read]), MAX([Write]), MAX([Own]), MAX([Destroy])
FROM
(
  SELECT CustID,
   [Read]    = CASE permission WHEN 'read'    THEN 'X' END,
   [Write]   = CASE permission WHEN 'write'   THEN 'X' END,
   [Own]     = CASE permission WHEN 'own'     THEN 'X' END,
   [Destroy] = CASE permission WHEN 'destroy' THEN 'X' END
  FROM dbo.rights
) AS src
GROUP BY custID;

请不要使用单引号来分隔列或表'alias'。不仅不推荐使用语法,而且还使实体看起来像字符串文字。如果必须对其进行转义(例如,如果您选择了错误的列名),请使用[square brackets].

于 2013-03-20T00:29:35.980 回答
0

您可以PIVOT直接在一个查询中使用表运算符来执行此操作,而不是使用这些CASE表达式。

它将执行您正在寻找的进一步步骤,即使用CASE表达式传播记录后对记录进行分组。就像是:

SELECT 
  CustId, 
  read, 
  write, 
  own, 
  Destroy
FROM
( 
   SELECT custid, permission, x
   FROM tablename
) AS t
PIVOT
(
   MAX(x)
   FOR permission IN('read', 
                     'write', 
                     'own', 
                     'Destroy')
) AS p;

在您的查询中,如果x是字符串文字而不是标识符,那么您通常可以在锚查询中将其选择为带有别名的字符串文字,SELECT custid, permission, 'x' AS x FROM tablename那么上面的查询应该可以正常工作。

于 2013-03-20T00:35:07.860 回答