根据另一个 select 中的列名进行选择(EVAL?)

Selecting based on column names from another select (EVAL?)

我有 2 个 table,一个是需要计数的列名列表,另一个是要计数的数据

Table A
ProgramId  ColumnName
1          Country
1          Gender
2          AgeRange
2          Region

Table B
ProgramId  Country  Gender  AgeRange  Region
1          USA      M       18-25     Midwest
1          USA      F       <18       Northeast
1          MEX      M       <18       South
2          USA      M       18-25     Midwest
2          USA      M       26-35     Midwest

给定一个特定的 ProgramId,我需要 table A 中的每一列的列表与每个值连接并从 table B

中计数

需要示例输出(参数:@ProgramId = 1)

ColumnName  ColumnValue  ValueCount
Country     USA          2
Country     MEX          1
Gender      M            2
Gender      F            1

根据我能够找到的谷歌搜索,我需要某种动态声明。这对我来说很好,因为唯一有权访问 table A 的人将是内部开发人员。

第一步是生成代码。第二个是运行吧。

假设您的列没有特殊名称或奇怪字符:

select @sql = ('select ' + cols +
               ', count(*) as ValueCount from b group by ' + cols
              )
from (select stuff((select ', ' + a.ColumnName
                    from a
                    where programid = @programid
                    for xml path ('')
                   ), 1, 2, ''
                  ) as cols
     ) x;

exec sp_executesql @sql;

SQL Fiddle

MS SQL Server 2008 架构设置:

CREATE TABLE TableA (ProgramId INT, ColumnName VARCHAR(20))
INSERT INTO TableA VALUES
(1          ,'Country'),
(1          ,'Gender'),
(2          ,'AgeRange'),
(2          ,'Region')


CREATE TABLE TableB (ProgramId VARCHAR(20), Country VARCHAR(20), 
      Gender VARCHAR(20), AgeRange VARCHAR(20), Region VARCHAR(20))
INSERT INTO TableB VALUES
('1'          ,'USA'      ,'M'       ,'18-25'     ,'Midwest'),
('1'          ,'USA'      ,'F'       ,'<18'       ,'Northeast'),
('1'          ,'MEX'      ,'M'       ,'<18'       ,'South'),
('2'          ,'USA'      ,'M'       ,'18-25'     ,'Midwest'),
('2'          ,'USA'      ,'M'       ,'26-35'     ,'Midwest')

查询 1:

;With x AS 
(
Select * 
From TableB 
      UNPIVOT(ColumnValue FOR ColumnName IN (Gender, Country))up
)
Select x.ColumnName
      ,x.ColumnValue
      ,COUNT(x.ColumnValue) ValueCount
From x 
inner join TableA a ON x.ColumnName = a.ColumnName
WHERE x.ProgramId = 1   --<-- or maybe the parameter @ProgramId
GROUP BY x.ColumnName,x.ColumnValue

Results:

| ColumnName | ColumnValue | ValueCount |
|------------|-------------|------------|
|    Country |         MEX |          1 |
|    Country |         USA |          2 |
|     Gender |           F |          1 |
|     Gender |           M |          2 |