2010-06-25 2 views
0

:SQL Server : 열 이름에 단어가 포함되어 있으면 SUM 열 값을 어떻게 계산합니까? 내 SQL 테이블에서

Period| Brand A small Bags| Brand A big bags| Brand D Shoes| ...| Brand X Shoes 
2010 | 10    | 20    | 30   | ...| 200   

어떻게 열 이름에 특정 단어 (예를 들어, 신발)을 포함하는 열 합계합니까?

예상 결과 :

Period | Sum of Bags | Sum of Shoes | .. 
2010 | 30   | 230   | .. 
+0

왜 테이블이 이렇게 구조화되어 있는지 말해 줄 수 있습니까? –

+0

"브랜드 A"가 "브랜드 Z"로 변경되는 것과 같이 브랜드의 이름이 변경되면 어떻게됩니까? "Shoes"를 "Dress Shoes"와 "Athletic Shoes"로 나누어야 할 경우 어떻게됩니까? – Thomas

+0

다른 응용 프로그램에서 가져오고 읽을 수 있도록이 구조의 데이터가 필요합니다. 제한 사항을 실현했습니다. 그래서 구조를 변경하고 나중에 SQL에서 그것을 바꿀 것입니다 – marilyn

답변

10

당신하지 동적 SQL 없이는와 INFORMATION_SCHEMA 테이블을 조회하거나 하드 코딩 할 수 있습니다. 다음과 같이 데이터를 재구성 할 수 있습니까?

Brands (BrandId, BrandName) 
ItemTypes (ItemId, ItemName) 
Stock(BrandId, ItemId, Period, Quantity) 

편집

이뿐만 아니라 부하 많은 이유는 아마하지만 여기에 현재의 테이블 구조가 문제가 몇 가지 이유가 있습니다.

  • 테이블의 최대 열 수는 1024이므로 모든 브랜드/항목 순열에 대해 열을 계속 추가 할 수 없습니다.

  • 브랜드가 가방과 신발을 만드는 경우 브랜드에 대한 정보를 여러 번 반복합니다. 이러한 정보가 반복 될 때마다 약간의 차이와 이상이 생길 수 있습니다. 또한 브랜드의 이름이 바뀌면 열을 업데이트하고 참조하는 모든 코드를 업데이트해야합니다.

  • 새 브랜드를 추가 할 때 모든 순열을 하드 코딩하지 않고 코드를 업데이트하지 않고 모든 가방을 합산하는 것과 같은 간단한 계산은 할 수 없습니다.

  • 신발을 제공하는 모든 브랜드의 이름을 가져 오는 것과 같이 전혀 쿼리를 수행 할 수 없거나 최소한 어려운 것은 아닙니다.

+0

어떻게 동적 SQL과 함께합니까? 감사합니다 :) – marilyn

+1

@marilyn - 동적 SQL에서는 가능하지는 않지만 권하고 싶지 않습니다! 가장 좋은 방법은 열 이름을 구문 분석하여이 데이터를 추출하는 것이 아니라 위에서 제안한대로 데이터를 재구성하는 것입니다. –

+1

"몇 가지 쿼리를 수행 할 수는 없지만 (또는 적어도 별 어려움없이)"- 머리를 감싸십시오 : '2010 년의 구두 합계'와 같은 간단한 SQL DML을 작성할 수 있다면 SQL DDL은 다음과 같습니다. 잘못된. – onedaywhen

0
SELECT PERIOD, [Brand A small Bags] + [Brand A big bags] [Sum of Bags] ... etc 
2

당신은 (전용 콘텐츠에) 열 이름에 와일드 카드를 사용할 수 없습니다.

당신의 라인을 따라 쿼리를 구성 할 수 있도록 열 수는 변경되지해야합니다

select period, sum([Brand A small bags]) + sum([Brand A big bags]) as [sum of bags], 
    sum([Brand D shoes]) + sum([Brand X shoes]) as [sum of shoes] 
from yourtable 
group by period 

을하지만 마틴 스미스에서 알 수 있듯이, 데이터를 재구성하는 것이 좋습니다 것입니다.

1

글쎄, 나는 더 깊이 SQL을 배우고 있기 때문에 나 자신을위한 연습 문제로 해결하려고 노력했다. 나는 주어진 스키마의 문제점들이 내가 그것에 대해 아무 말도하지 않을 정도로 잘 문서화되어 있다고 생각한다.

이 코드를 작동 시키려면 소스 데이터의 열이 물리적 인 열이어야합니다 (즉, 테이블 변수 또는보기의 열이 아님). 가방과 신발 이외의 다른 유형이있는 경우이 코드를 함수와 기타 등등으로 추상화 할 수 있습니다. 알고리듬을 쓰고 싶었습니다. 이것이 제대로 작동하기위한 다른 많은 경고가 있지만, 언급 한 바와 같이, 비정규 화 된 데이터는 완전한 경고 세트를 가지고 있습니다.

그래서 여기에 우리가 간다 :

편집 : 버전 2. 감사 마틴이 함께 도와. 그건 정말 깔끔한 트릭이지만 사용하는 것은 드문 일입니다.

필자는 열 이름이 검색 패턴과 일치한다고 가정합니다 (충분히 하드 코딩되었으므로 귀찮은 확인이 필요합니다).

DECLARE @sql nvarchar(max) 
SET @sql = 'SELECT Period, ' 


-- Build column sum for bags 
DECLARE @bagsColumns nvarchar(max) 

SELECT 
    @bagsColumns = COALESCE(@bagsColumns + '+', N'') + '[' + COLUMN_NAME + ']' 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_NAME = 'SumTest' AND COLUMN_NAME LIKE '%bags%' 

SET @sql = @sql + @bagsColumns + ' AS ''Sum of Bags'', ' 


-- Build column sum for shoes 
DECLARE @shoesColumns nvarchar(max) 

SELECT 
    @shoesColumns = COALESCE(@shoesColumns + '+', N'') + '[' + COLUMN_NAME + ']' 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_NAME = 'SumTest' AND COLUMN_NAME LIKE '%shoes%' 

SET @sql = @sql + @shoesColumns + ' AS ''Sum of Shoes''' 


SET @sql = @sql + ' FROM SumTest' 

EXEC(@sql) 
+1

커서'DECLARE @BagSum nvarchar (max);를 피할 수 있습니다. INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'BagsAndShoes'및 COLUMN_NAME LIKE 'bags %'에서 @BagSum = COALESCE (@BagSum + '+', 'SELECT 기간') + '['+ COLUMN_NAME + ']'선택하십시오. IF (@@ ROWCOUNT> 0) BEGIN 설정 @BagSum = @BagSum + 'AS SumOfBags From BagsAndShoes'; EXEC sp_executesql @BagSum END' –

+1

@Martin : 팁 주셔서 대단히 감사합니다! 내가 말했듯이, 나는 아직도 배우고있다. 나는 버전 2로 나의 대답을 업데이트했다. –

+0

좋아 보인다. 'INFORMATION_SCHEMA.COLUMNS' (아래)의 하나의 질의로 가능할 수도 있지만, 당신이 가지고있는 것처럼 더 명확 할 수도 있습니다. –