2009-11-10 91 views
0

我有一張桌子,裏面儲存了我曾經工作過的各種客戶,由政府和商業專欄分隔。問題在於任何一列中的客戶端數量可能都不一致。當我做一個SELECT時,我在不規則的地方結束NULL值,因爲我想不出一個乾淨的方式來排序結果集。例如,以下是可能的直SELECT(沒有ORDER BY):表格變量:是否有更清潔的方法?

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

正如你所看到的,有在政府列NULL值,因爲有更多的商業客戶比政府。這可能會隨時發生變化,並且不能保證哪個列將具有更多值。爲了在結果集中消除空白值的渲染,我決定在表變量中執行兩個單獨的SELECT(一個用於政府客戶端,另一個用於Commercial),然後選擇一個最終時間,將它們連接在一起:

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

從設計上來看,我不明白爲什麼你需要兩個表,甚至兩欄政府/商業。您可以在表Clients中使用OrganizationType的分類器列。例如:

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

對於OrganizationType你可以使用:G = GOV,B =商務/商業,C =慈善事業。在查詢表格時,在ORDER BY和GROUP BY中使用OrganizationType

如果有對政府網站和商業客戶的一些具體列,然後繼續在Customer表中的所有公共列,並在不同的分型移動特定的列GovernmentCommercial表爲this example。在這個例子中,書和雜誌是出版物的類型 - 在你的例子中,政府和商業是顧客類型。

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

謝謝你的迴應。我不是爭論性的(我真的不明白),但是那會給我買什麼?我認爲這是足夠的,只需按順序顯示它們(因此加入行號)。順便說一句,我認爲你的意思是全外聯接。;-) – senfo 2009-11-10 13:15:48

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 2009-11-10 05:22:16

+0

好眼睛。現在已經修復了。 – dnagirl 2009-11-10 13:02:25

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 - 獲得羣集索引的優點。

相關問題