如何计算行并将它们转移到单独的列?

How to count rows and transfer them to separate columns?

我有 table 这样的:

Castomer_ID Survay_result
John        Good
Ben         Bad
John        Bad
John        Good
Ben         Bad
Ben         Good

我想创建查询 return 这个结果:

Castomer_ID Good    Bad
John        2       1
Ben         1       2

我试过为此使用子查询:

SELECT Castomer_ID AS temp_Castomer_ID,
    (SELECT COUNT(Survay_result)
     FROM test1
     WHERE
        temp_Castomer_ID = Castomer_ID
        AND
        template_id = Good) AS 'Good',
    (SELECT COUNT(Survay_result)
     FROM test1
     WHERE
        temp_Castomer_ID = Castomer_ID
        AND
        template_id = Bad) AS 'Bad',
FROM test
GROUP BY 
    Castomer_ID

我看到下一个错误信息:

Msg 207, Level 16, State 1, Line 5
Invalid column name 'temp_Castomer_ID'.
Msg 207, Level 16, State 1, Line 11
Invalid column name 'temp_Castomer_ID'.

我做错了什么?请帮忙

使用 table 别名并限定列以解决名称冲突。

SELECT t.castomer_id,
       (SELECT count(*)
               FROM test AS tg
               WHERE tg.castomer_id = t.castomer_id
                     AND tg.survay_result = 'Good') AS good,
       (SELECT count(*)
               FROM test AS tb
               WHERE tb.castomer_id = t.castomer_id
                     AND tb.survay_result = 'Bad') AS bad
       FROM test AS t
       GROUP BY t.castomer_id;

另外:

  • 您查询中的 objects 与给定的示例不完全匹配。你会自己解决这个问题。
  • 不要习惯于对列别名等标识符使用单引号。是的,遗憾的是 SQL 服务器在某些地方接受了这一点,但在 SQL 中,单引号通常用于字符串(或日期...)文字。如果您曾经使用过另一个 DBMS(或者未来的 SQL 服务器版本对此变得更加理智),您可能会遇到错误。对其中包含特殊字符或区分大小写的标识符使用方括号,或者最好根本不使用特殊字符和区分大小写的标识符。标识符不需要“漂亮”、“漂亮”headers,这是表示层的工作。
  • 但是你必须引用字符串文字。

您还可以使用条件聚合来代替子查询。这个可能性能更好,你需要测试一下。

SELECT t.castomer_id,
       count(CASE
               WHEN t.survay_result = 'Good' THEN
                 1
             END) AS good,
       count(CASE
               WHEN t.survay_result = 'Bad' THEN
                 1
             END) AS bad
       FROM test AS t
       GROUP BY t.castomer_id;

我建议你实际上只使用带有 JOIN:

的条件聚合
SELECT t.Castomer_ID AS temp_Castomer_ID, --Customer doesn't have an a
       COUNT(CASE t1.Survay_result WHEN 'Good' THEN 1 END) AS Good, --Don't use literal strings for aliases. Survey doesn't have an a
       COUNT(CASE t1.Survay_result WHEN 'Bad' THEN 1 END) AS Bad --Don't use literal strings for aliases. Survey doesn't have an a
FROM dbo.test t
     LEFT JOIN dbo.test1 t1 ON t.Castomer_ID = t1.Castomer_ID
GROUP BY t.Castomer_ID;
    create table #temp1 (Castomer_ID varchar(5),Survay_result varchar(5))
insert into #temp1 values
('John','Good'),('Ben',' Bad'),('John','Bad'),('John','Good'),('Ben',' Bad'),('Ben',' Good')

select Castomer_ID,sum(good)[Good],sum(bad)[Bad] from(
select Castomer_ID, case when Survay_result like '%Good%'  then count(1) ELSE 0 end [Good],case when Survay_result like '%Bad%'  then count(1) ELSE 0 end [Bad] from #temp1 
group by Castomer_ID,Survay_result)h
group by Castomer_ID