문제

나는 일에 노력하고 보고서를 생성에서 부부의 데이터베이스 테이블이 있습니다.Simplified 버전 다음과 같이

Campaign
----------
CampaignID

Source
-----------------------
Source_ID | Campaign_ID

Content
---------------------------------------------------------
Content_ID | Campaign_ID | Content_Row_ID | Content_Value

보고서를 읽어야 다음과 같다:

CampaignID - SourceID - ContentRowID(Value(A)) - ContentRowID(Value(B))

는 ContentRowID(값(A))"을 의미를 찾을 행하는 주어진 CampaignID 및 ContentRowId 의"A"와 다음 ContentValue 는 행"

기본적으로,나는"pivot"(제 생각에는 그게 올바른 기간)행으로 열...

그것은 Oracle10g 데이터베이스...

어떤 방법이 있나요?

도움이 되었습니까?

해결책

이것은 내 첫 찌르기입니다. 컨텐츠 테이블의 내용에 대해 더 많이 알게되면 개선됩니다.

먼저 임시 테이블이 필요합니다.

CREATE TABLE pivot (count integer);
INSERT INTO pivot VALUES (1);
INSERT INTO pivot VALUES (2);

이제 쿼리 할 준비가되었습니다.

SELECT campaignid, sourceid, a.contentvalue, b.contentvalue
FROM content a, content b, pivot, source
WHERE source.campaignid = content.campaignid
AND pivot = 1 AND a.contentrowid = 'A'
AND pivot = 2 AND b.contentrowid = 'B'

다른 팁

Bill Karwin은 이것을 언급하지만, 이것이 매우 명확하게 지적 될 가치가 있다고 생각합니다.

SQL은 당신이 요구하는 일을하지 않으므로, 당신이 얻는 "솔루션"은 Kludge가 될 것입니다.

만약 너라면 알다, 확실히, 그것은 항상 Oracle 10에서 실행될 것입니다. 그러면 Walter Mitty의 Crosstabulation이 그렇게 할 수 있습니다. 올바른 방법은 쿼리와 애플리케이션 코드에서 가장 쉬운 정렬 순서 조합을 작동하여 올바르게 배치하는 것입니다.

  • 다른 데이터베이스 시스템에서 작동하며
  • 그것은 다른 레이어가 무너질 위험이 없습니다 (예 :> 255 열에 문제가있는 MySQL을 기억합니다. 인터페이스 라이브러리 DB 자체뿐만 아니라 대처?)
  • (보통) 그다지 어렵지 않습니다.

필요하다면, 당신은 Content_Row_IDs 먼저, 필요한 행을 요청하십시오. CampaignID, ContentRowID, 이것은 각각 (인구가 많은) 셀을 왼쪽에서 오른쪽으로 라인 별 순서로 제공합니다.


추신.

현대인이 SQL이 가지고 있지 않은 것으로 생각하는 것들이 많이 있습니다. 이것은 하나입니다. 생성 된 범위는 또 다른, 재귀 적 폐쇄, 파라 메트릭입니다. ORDER BY, 표준화 된 프로그래밍 언어 ... 목록이 계속됩니다. (하지만 분명히 ORDER BY)

동적 수의 열이없고 데이터 세트가 너무 크지 않으면이 작업을 수행 할 수 있습니다 ...

SELECT CampaignID, SourceID, 
   (SELECT Content_Value FROM Content c 
      WHERE c.Campaign_ID=s.Campaign_ID 
      AND Content_Row_ID = 39100 
      AND rownum<=1) AS Value39100,
   (SELECT Content_Value FROM Content c 
      WHERE c.Campaign_ID=s.Campaign_ID 
      AND Content_Row_ID = 39200 
      AND rownum<=1) AS Value39200
FROM Source s;

각 추가 Content_row_id에 대한 서브 쿼리를 반복하십시오.

표준 SQL에서이를 수행하려면 Content_Row_ID의 모든 뚜렷한 값을 알고 별도의 값에 따라 조인해야합니다. 그런 다음 Content_ROW_ID의 별개의 값 당 열이 필요합니다.

SELECT CA.Campaign_ID, 
  C1.Content_Value AS "39100",
  C2.Content_Value AS "39200",
  C3.Content_Value AS "39300"
FROM Campaign CA
  LEFT OUTER JOIN Content C1 ON (CA.Campaign_ID = C1.Campaign_ID 
    AND C1.Content_Row_ID = 39100)
  LEFT OUTER JOIN Content C2 ON (CA.Campaign_ID = C2.Campaign_ID 
    AND C2.Content_Row_ID = 39200)
  LEFT OUTER JOIN Content C3 ON (CA.Campaign_ID = C3.Campaign_ID 
    AND C3.Content_Row_ID = 39300);

뚜렷한 값의 수가 커짐에 따라이 쿼리는 너무 비싸서 효율적으로 실행할 수 없습니다. 데이터를보다 간단하게 가져 와서 PL/SQL 또는 응용 프로그램 코드로 재발하는 것이 더 쉽습니다.

빌 Karwin 및 Anders Eurenius 은 올바른 해결책이 없다는 간단하도 없 솔루션에는 모든 경우의 수는 결과 열의 값을 미리 알려지지 않습니다.Oracle11g 는 간단한 다과 피벗 운영자, 하지만 열 여전히 될 사전에 알려져 있고 맞지는 10g 기준의 질문입니다.

동적 수의 열이 필요하다면, 나는 이것이 내 지식을 초과하는 표준 SQL에서 수행 할 수 있다고 생각하지 않습니다. 그러나 그것을 할 수있는 Oracle의 특징이 있습니다. 몇 가지 자료를 찾았습니다.

http://www.sqlsnippets.com/en/topic-12200.html

http://asktom.oracle.com/pls/asktom/f?p=100:11:0:::p11_Question_id:124812348063#4109761656309

"Oracle, 완전한 참조"가있는 경우 "옆에 테이블을 돌리는"이라는 제목의 섹션을 찾으십시오. 이것은 피벗을 수행하기위한 자세한 예와 지침을 제공하지만, 내가 가진 판은 그것을 피벗이라고 부르지 않습니다.

"테이블 피봇 팅"의 또 다른 용어는 CrosStabulation입니다.

CrosStabulation을 수행하는 데 가장 쉬운 도구 중 하나는 MS Access입니다. MS 액세스가 있고 액세스 데이터베이스에서 소스 테이블로 테이블 링크를 설정할 수있는 경우 이미 중간에 있습니다.

이 시점에서 "쿼리 마법사"를 크랭크하고 Crosstab 쿼리를 작성하도록 요청할 수 있습니다. 마법사가 묻는 질문에 대답하는 것만 큼 쉽습니다. 이 솔루션의 불행한 측면은 SQL View의 결과 쿼리를 보면 SQL의 액세스 방언에 특유한 SQL이 표시되며 일반적으로 다른 플랫폼에서 사용할 수없는 SQL이 표시됩니다.

Oracle 웹 사이트에서 간단한 분석 도구를 다운로드하고 해당 도구 중 하나를 사용하여 CrosSabulation을 수행 할 수도 있습니다.

다시 한 번, SQL에서 "Oracle"으로 실제로하고 싶다면 완전한 참조가 도움이 될 것입니다.

앞에 열의 수를 모르는 경우 일반 SQL 쿼리를 다시 가져 와서 여기에 나열된 것처럼 서버 사이드 코드를 사용하십시오. DataGrid 및 SQL 쿼리를 채우십시오

나는이 SQL로 솔루션을했다. 나는 행이 클래스의 수가되었고 열은 매달 각 classe의 sumary가 될 필요가 있었기 때문에 첫 번째 열은 행의 수주이고 각 Ohters 열은 매월의 sumary이고 마지막 행은 Sumary입니다. 매달 완전한 열의.

행운을 빕니다

Select DS.Cla,
Sum(case
when (Extract(year from DS.Data) =:intYear) then DS.PRE
else 0
end) as ToTal,
Sum(case
when (Extract(month from DS.Data) =1) then DS.PRE
else 0
end) as Jan,
Sum(case
when (Extract(month from DS.Data) =2) then DS.PRE
else 0
end) as FEV,
Sum(case
when (Extract(month from DS.Data) =3) then DS.PRE
else 0
end) as MAR,
Sum(case
when (Extract(month from DS.Data) =4) then DS.PRE
else 0
end) as ABR,
Sum(case
when (Extract(month from DS.Data) =5) then DS.PRE
else 0
end) as MAI,
Sum(case
when (Extract(month from DS.Data) =6) then DS.PRE
else 0
end) as JUN,
Sum(case
when (Extract(month from DS.Data) =7) then DS.PRE
else 0
end) as JUL,
Sum(case
when (Extract(month from DS.Data) =8) then DS.PRE
else 0
end) as AGO,
Sum(case
when (Extract(month from DS.Data) =9) then DS.PRE
else 0
end) as SETE,
Sum(case
when (Extract(month from DS.Data) =10) then DS.PRE
else 0
end) as OUT,
Sum(case
when (Extract(month from DS.Data) =11) then DS.PRE
else 0
end) as NOV,
Sum(case
when (Extract(month from DS.Data) =12) then DS.PRE
else 0
end) as DEZ
from Dados DS
Where DS.Cla > 0
And Extract(Year from DS.Data) = :intYear
group by DS.CLA

Union All

Select 0*count(DS.cla),  0*count(DS.cla),
Sum(case
when (Extract(month from DS.Data) =1) then DS.PRE
else 0
end) as JAN,
Sum(case
when (Extract(month from DS.Data) =2) then DS.PRE
else 0
end) as FEV,
Sum(case
when (Extract(month from DS.Data) =3) then DS.PRE
else 0
end) as MAR,
Sum(case
when (Extract(month from DS.Data) =4) then DS.PRE
else 0
end) as ABR,
Sum(case
when (Extract(month from DS.Data) =5) then DS.PRE
else 0
end) as MAI,
Sum(case
when (Extract(month from DS.Data) =6) then DS.PRE
else 0
end) as JUN,
Sum(case
when (Extract(month from DS.Data) =7) then DS.PRE
else 0
end) as JUL,
Sum(case
when (Extract(month from DS.Data) =8) then DS.PRE
else 0
end) as AGO,
Sum(case
when (Extract(month from DS.Data) =9) then DS.PRE
else 0
end) as SETE,
Sum(case
when (Extract(month from DS.Data) =10) then DS.PRE
else 0
end) as OUT,
Sum(case
when (Extract(month from DS.Data) =11) then DS.PRE
else 0
end) as NOV,
Sum(case
when (Extract(month from DS.Data) =12) then DS.PRE
else 0
end) as DEZ
from Dados DS
Where DS.Cla > 0
And Extract(Year from DS.Data) = :intYear
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top