2009-11-10 3 views
0

저는 정부와 상업 칼럼으로 구분 된 다양한 클라이언트를 저장하는 테이블을 가지고 있습니다. 문제는 두 열에 균등하지 않은 수의 클라이언트가있을 수 있다는 것입니다. 내가 SELECT를 할 때 결과 집합을 정렬하는 깔끔한 방법을 생각할 수 없기 때문에 불규칙한 위치에 NULL 값이 생깁니다. 예를 들어, 다음은 직선 SELECT (없음 ORDER) 가능합니다 : 당신이 볼 수 있듯이 정부보다 더 많은 기업 고객이 있기 때문에테이블 변수 : 더 깨끗한 방법이 있습니까?

Government | Commercial 
DOD  | IBM 
DOS  | Microsoft 
      | Novell 
DVA  | Oracle

는 정부 열에 NULL 값이 있습니다. 이것은 언제든지 변경 될 수 있으며 더 많은 열이 더 많은 값을 가질 것이라는 보장은 없습니다. 결과 집합의 중간에 공백 값을 사용하여 렌더링을 제거하기 위해 테이블 ​​변수 (정부 고객 용과 상업용)에 대해 두 개의 SELECT를 수행하기로 결정한 다음 마지막으로 SELECT를 선택하여 다시 결합합니다 (

).
DECLARE @Government TABLE 
(
    Row int, 
    PortfolioHistoryId uniqueidentifier, 
    Government varchar(40), 
    GovernmentPortfolioContentId uniqueidentifier 
) 

DECLARE @Commercial TABLE 
(
    Row int, 
    PortfolioHistoryId uniqueidentifier, 
    Commercial varchar(40), 
    CommercialPortfolioContentId uniqueidentifier 
) 

INSERT INTO @Government 
    SELECT 
     (ROW_NUMBER() OVER (ORDER BY Government)) AS Row, 
     PortfolioHistoryId, 
     Government, 
     GovernmentPortfolioContentId 
    FROM dbo.PortfolioHistory 
    WHERE Government IS NOT NULL 

INSERT INTO @Commercial 
    SELECT 
     (ROW_NUMBER() OVER (ORDER BY Commercial)) AS Row, 
     PortfolioHistoryId, 
     Commercial, 
     CommercialPortfolioContentId 
    FROM dbo.PortfolioHistory 
    WHERE Commercial IS NOT NULL 

SELECT 
    g.Government, 
    c.Commercial, 
    g.GovernmentPortfolioContentId, 
    c.CommercialPortfolioContentId 
FROM @Government AS g 
FULL OUTER JOIN @Commercial AS c ON c.Row = g.Row

나는이 쿼리에 불만이있는 것은 아니지만 (어쩌면 내가해야 할 것 같은), 이것을 구현하는 더 깨끗한 방법이 있습니까?

답변

1

, 내가 볼 수없는, 심지어 정부/상업의 두 개의 기둥도 있습니다. OrganizationType에 대한 분류 자 ​​열이있는 표 Clients을 사용할 수 있습니다. 예를 들면 : OrganizationType를 들어

DECLARE TABLE Customer (
ID int 
,Name varchar(50) 
,OrganizationType char(1) 
,Phone varchar(12) 
) 

당신이 사용할 수 있습니다 : G = 모양의 정부, B = 비즈니스/상업, C는 = 자선. 표를 질의 할 때 ORDER BY와 GROUP BY에서 OrganizationType을 사용하십시오. 모양의 정부 및 비즈니스 고객을위한 일부 특정 열이있는 경우

, 다음 Customer 테이블의 모든 일반적인 열을 유지하고 this example 같이 별도의 하위 유형에 GovernmentCommercial 테이블을 특정 열을 이동합니다. 예를 들어, 서적과 잡지는 출판의 유형입니다. 예를 들어, 정부와 상업은 고객 유형입니다.

1

정부 테이블을 상용 테이블에 연결할 governID가 있어야합니다. 상업용 테이블에 값을 삽입 할 때 상업용 행을 사용할 위치에 governID를 삽입해야합니다.

Government   Commercial 
governID  | NAME  commID  | com_govID | Name 
    1    BIR   1    1   Netopia 
           2    1   SM Mall 

그래서 쿼리하면됩니다.

SELECT 
    g.Government, 
    c.Commercial, 
    g.GovernmentPortfolioContentId, 
    c.CommercialPortfolioContentId 
FROM @Government AS g 
FULL INNER JOIN @Commercial AS c ON c.governID = com_govID 
+0

응답 해 주셔서 감사합니다. 나는 논쟁 적이 지 않다. (나는 정말로 이해하지 못한다.)하지만 그게 나에게 무엇을 사주 는가? 나는 그것들을 단순히 순서대로 표시하는 것만으로 충분하다고 생각했다. (따라서 행 번호에 합류). 그건 그렇고, 너는 FULL OUTER JOIN을 의미한다고 생각해.;-) – senfo

0

일반적으로 렌더링 문제는 응용 프로그램 계층에서 처리해야합니다. 똑바로 SELECT를 수행 한 다음 원하는 형식으로 처리하십시오.

그래서 :

SELECT DISTINCT client, client_type FROM clients table; 

그런 다음 응용 프로그램 계층에서 (나는 신속하고 더러운 PHP를 사용합니다) : 두 개의 테이블이 필요한 이유

디자인 관점에서
foreach($row = $result->fetch_assoc()) { 
    if($row['client_type']=='gov') { 
    $gov[]=$row['client']; 
    } else { 
    $com[]=$row['client']; 
    } 
} 

$limit=(count($gov)>$count($com)) ? count($gov) : count($com); 

echo '<table><tr><th>Gov</th><th>Com</th><tr>'; 
for($i=0; $i< $limit; $i++) { 
    echo "<tr><td>{$gov[$i]}</td><td>{$com[$i]}</td></tr>\n"; 
} 
echo '</table> 
+0

{$ com [$ i]}을 (를) 의미하는 것처럼 보입니다. – Don

+0

좋은 눈. 이제 해결되었습니다. – dnagirl

1
SELECT 
    Government, 
    Commercial, 
    GovernmentPortfolioContentId, 
    CommercialPortfolioContentId 
FROM dbo.PortfolioHistory 
ORDER BY 
    CASE WHEN Government is null THEN 2 ELSE 1 END, 
    CASE WHEN Commercial is null THEN 2 ELSE 1 END, 
    Government, 
    Commercial 

제외 : 당신의 변수 테이블에서 "줄"열이 PRIMARY KEY로 선언되어야한다 - 클러스터 된 인덱스의 장점을 얻을 수 있습니다.

관련 문제