如何选择多列计数

时间:2019-01-30 10:49:32

标签: c# sql sql-server

我有这个视图

-----------------------------------
ID    1stChoice  2Choice  3rdChoice
-----------------------------------
1  -  AA       -   BB    -   CC
2  -  CC       -   BB    -   AA
3  -  AA       -   CC    -   BB
4  -  BB       -   AA    -   CC
5  -  AA       -   CC    -   BB

,我需要显示一个字段被选为1stChoice,2ndChoice and 3rdChoice的次数的报告。

我尝试了此查询,该查询非常适合单列

select 1stChoice,COUNT(*) as 'Count' from myView group by 1stChoice;

1stChoice - Count
-----------------
AA        -   3       
BB        -   1       
CC        -   1       

但这是我想要的输出外观

------------------------------------
Field -1stChoice  2Choice  3rdChoice
------------------------------------
AA    -  3       -   1    -   1
BB    -  1       -   2    -   2
CC    -  1       -   2    -   2

是否有一个Wayi无需为视图中的每一列写select 1stChoice,COUNT(*) as 'Count' from myView group by 1stChoice;就能实现这一目标?
我见过Select multiple counts from one database table in one sql command access和其他人,但没有一个人解决了我的问题。

5 个答案:

答案 0 :(得分:3)

使用数据透视的示例;

SELECT [ChosenValue], [pvt].[1stChoice], pvt.[2ndChoice], pvt.[3rdChoice]
FROM (
    SELECT Id, '1stChoice' Choice, [1stChoice] [ChosenValue]
    FROM MyView
    UNION
    SELECT Id, '2ndChoice' Choice, [2ndChoice]
    FROM MyView
    UNION
    SELECT Id, '3rdChoice' Choice, [3rdChoice]
    FROM MyView
) AS tbl
PIVOT (
    COUNT(Id)
    FOR Choice IN ([1stChoice], [2ndChoice], [3rdChoice])
) as pvt

结果;

ChosenValue 1stChoice   2ndChoice   3rdChoice
AA          3           1           1
BB          1           2           2
CC          1           2           2

答案 1 :(得分:2)

您可以尝试执行以下操作,但是如果由于有多个OR的联接而导致记录很多,则性能可能会提高,并且如果您打算选择许多可能的选择,则绝对不利于扩展(无答案)

IF OBJECT_ID('tempdb..#myView') IS NOT NULL
    DROP TABLE #myView

CREATE TABLE #myView (
    ID INT IDENTITY,
    [1stChoice] VARCHAR(10),
    [2ndChoice] VARCHAR(10),
    [3rdChoice] VARCHAR(10))

INSERT INTO #myView (
    [1stChoice],
    [2ndChoice],
    [3rdChoice])
VALUES
    ('AA', 'BB', 'CC'),
    ('CC', 'BB', 'AA'),
    ('AA', 'CC', 'BB'),
    ('BB', 'AA', 'CC'),
    ('AA', 'CC', 'BB')


;WITH AvailableAnswers AS
(
    SELECT T.[1stChoice] AS Field FROM #myView AS T
    UNION
    SELECT T.[2ndChoice] FROM #myView AS T
    UNION
    SELECT T.[3rdChoice] FROM #myView AS T
)
SELECT
    Field = A.Field,
    [1stChoice] = COUNT(CASE WHEN V.[1stChoice] = A.Field THEN 1 END),
    [2ndChoice] = COUNT(CASE WHEN V.[2ndChoice] = A.Field THEN 1 END),
    [3rdChoice] = COUNT(CASE WHEN V.[3rdChoice] = A.Field THEN 1 END)
FROM
    AvailableAnswers AS A
    INNER JOIN #MyView AS V ON 
        A.Field = V.[1stChoice] OR
        A.Field = V.[2ndChoice] OR
        A.Field = V.[3rdChoice]
GROUP BY
    A.Field

结果:

Field   1stChoice   2ndChoice   3rdChoice
AA      3           1           1
BB      1           2           2
CC      1           2           2

答案 2 :(得分:0)

您可能需要执行unpivotpivot

SELECT Field, 
       SUM(CASE WHEN choice = '1stChoice' THEN 1 ELSE 0 END) AS [1stChoice],
       SUM(CASE WHEN choice = '2Choice' THEN 1 ELSE 0 END) AS [2stChoice],
       SUM(CASE WHEN choice = '3rdChoice' THEN 1 ELSE 0 END) AS [3stChoice]
FROM myView mv CROSS APPLY
     ( VALUES ('1stChoice', [1stChoice]), ('2Choice', [2Choice]), ('3rdChoice', [3rdChoice])
     ) mvv (choice, Field)
GROUP BY Field;

答案 3 :(得分:0)

使用c#linq:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication98
{
    class Program
    {
        static void Main(string[] args)
        {

            DataTable dt = new DataTable();
            dt.Columns.Add("ID", typeof(int));
            dt.Columns.Add("1stChoice", typeof(string));
            dt.Columns.Add("2Choice", typeof(string));
            dt.Columns.Add("3rdChoice", typeof(string));

            dt.Rows.Add(new object[] { 1, "AA", "BB", "CC" });
            dt.Rows.Add(new object[] { 2, "CC", "BB", "AA" });
            dt.Rows.Add(new object[] { 3, "AA", "CC", "BB" });
            dt.Rows.Add(new object[] { 4, "BB", "AA", "CC" });
            dt.Rows.Add(new object[] { 5, "AA", "CC", "BB" });

            string[] fields = dt.AsEnumerable().SelectMany(x => x.ItemArray.Skip(1).Select(y => (string)y)).Distinct().OrderBy(x => x).ToArray();

            DataTable pivot = new DataTable();
            pivot.Columns.Add("Field", typeof(string));
            pivot.Columns.Add("1stChoice", typeof(string));
            pivot.Columns.Add("2Choice", typeof(string));
            pivot.Columns.Add("3rdChoice", typeof(string));

            foreach (string field in fields)
            {
                int firstChoice = dt.AsEnumerable().Where(x => x.Field<string>("1stChoice") == field).Count();
                int secondChoice = dt.AsEnumerable().Where(x => x.Field<string>("2Choice") == field).Count();
                int thirdChoice = dt.AsEnumerable().Where(x => x.Field<string>("3rdChoice") == field).Count();
                pivot.Rows.Add(new object[] { field, firstChoice, secondChoice, thirdChoice }); 
            }

        }
    }

}

答案 4 :(得分:0)

您可以尝试以下查询。

 SELECT t1.1stChoice AS Field,
  (SELECT COUNT(*) FROM myView t2 WHERE t2.1stChoice= t1.1stChoice) 1stChoice,
  (SELECT COUNT(*) FROM myView t3 WHERE t3.2Choice  = t1.1stChoice) 2Choice  ,
  (SELECT COUNT(*) FROM myView t4 WHERE t4.3rdChoice= t1.1stChoice ) 3rdChoice
FROM myView t1
GROUP BY t1.1stChoice