2016-04-22 33 views
2

這樣的事情甚至可以做到嗎?對於我試圖製作的應用程序,用戶可以爲單個聯繫人輸入多個(或不包含)電子郵件,電話號碼和地址,但是在前向頁面上,我只想顯示第一個電話號碼,電子郵件地址和每個聯繫人的地址(如果有的話)。如何從所有列中只選擇一行,但是第一個

下面是檢索數據我的SQL查詢(請注意,它已經稍微修改了可讀性在實踐中,我不是一個cookie查詢SQL):

SELECT TC.FirstName + ' ' + TC.LastName AS FullName, TCE.EmailAddress, TCPN.PhoneNumber, TCA.[Address] + ", " + TCA.City + ', ' + TCA.[State] + ', ' + TCA.ZipCode AS FullAddress, TC.Notes 
FROM TContacts     AS TC 
INNER JOIN TContactEmails  AS TCE ON TCE.ContactID = TC.ContactID 
INNER JOIN TContactPhoneNumbers AS TCPN ON TCPN.ContactID = TC.ContactID 
INNER JOIN TContactAddresses AS TCA ON TCA.ContactID = TC.ContactID 
INNER JOIN TUserContacts  AS TUC ON TUC.ContactID = TC.ContactID 
INNER JOIN TUsers    AS TU ON TU.UserID = TUC.UserID 
WHERE TU.UserName = userCookie.Values["UserName"] 

期望的結果將是類似於使用SELECT TOP 1而不是僅僅使用SELECT,但是我不能那樣做,因爲那樣它只會顯示第一個聯繫人(FullName)。我需要查看每個姓名,但不是每個FullAddress,PhoneNumber或EmailAddress。

以下信息適用於是否存在與SQL查詢無關的其他解決方案。

此SQL查詢正在使用ASP.NET和C#代碼並通過ADO.NET命令調用的網頁中。一旦查詢被調用,所有使用的表被加載到一個DataAdapter對象中並用於動態填充一個ListView。下面是該代碼(的SQLStatement省略,因爲它本質上是上面列出):

 SqlConnection conn = new SqlConnection(WebConfigurationManager.ConnectionStrings["CPDM_NightingaleAConnectionString"].ConnectionString); 
     SqlCommand comm = new SqlCommand(sqlStatement, conn); 

     comm.CommandType = CommandType.Text; 
     comm.Connection = conn; 

     conn.Open(); 

     SqlDataAdapter dataAdapter = new SqlDataAdapter(comm); 
     DataSet ds = new DataSet(); 
     dataAdapter.Fill(ds, "TUsers, TUserContacts, TContactAddresses, TContactPhoneNumbers, TContactPhoneNumbers, TContactEmails, TContacts"); 
     lvContacts.DataSource = ds.Tables[0]; 
     lvContacts.DataBind(); 

     conn.Close(); 

爲ListView的ASP.NET代碼動態地創建基於該值的表,像這樣:

<asp:ListView ID="lvContacts" runat="server"> 
     <ItemTemplate> 
      <tr> 
       <td><asp:LinkButton ID="LinkButton1" runat="server" Text='<%# Eval("FullName") %>' /></td> 
       <td><asp:LinkButton ID="LinkButton2" runat="server" Text='<%# Eval("EmailAddress") %>' /></td> 
       <td><asp:LinkButton ID="LinkButton3" runat="server" Text='<%# Eval("PhoneNumber") %>' /></td> 
       <td><asp:LinkButton ID="LinkButton4" runat="server" Text='<%# Eval("FullAddress") %>' /></td> 
       <td><asp:LinkButton ID="LinkButton5" runat="server" Text='<%# Eval("Notes") %>' /></td> 
      </tr>  
     </ItemTemplate> 
    </asp:ListView> 

這絕不是像這樣的功能的最優雅的實現,但就目前而言,我不是我使用的任何工具的專家。任何有關這個話題的幫助將不勝感激。

作爲一個附錄,如果有人碰巧知道如何在SQL SELECT語句的中間添加一個換行符,它將在轉換爲HTML時顯示,這對組織FullAddress非常有用。 CHAR(10) + CHAR(13)的確看起來毫無價值。

+0

至於換行符,最好將您的SQL語句中的地址分隔開,並使用'<%#Eval(「Address」)+ Environment將其在鏈接按鈕代碼中分解。 NewLine + Eval(「City」)+「,」+ Eval(「State」)+「」+ Eval(「ZipCode」)%>' –

回答

4

可以使用子查詢通常是好這些類型的查找:

SELECT TC.FirstName + ' ' + TC.LastName AS FullName, 
(SELECT TOP 1 EmailAddress FROM TContactEmails WHERE ContactID = TC.ContactID) AS EmailAddress, 
(SELECT TOP 1 PhoneNumber FROM TContactPhoneNumbers WHERE ContactID = TC.ContactID) AS PhoneNumber, 
(SELECT TOP 1 [Address] + ", " + City + ', ' + [State] + ', ' + ZipCode FROM TContactAddresses WHERE ContactID = TC.ContactID) AS FullAddress, 
TC.Notes 
FROM TContacts     AS TC 
INNER JOIN TUserContacts  AS TUC ON TUC.ContactID = TC.ContactID 
INNER JOIN TUsers    AS TU ON TU.UserID = TUC.UserID 
WHERE TU.UserName = userCookie.Values["UserName"] 

或者,使用「默認」布爾表中,讓用戶輸入數據保存它們的默認地址,電話號碼等。

+1

這也是一個答案,但如果你在TContac中有大量的記錄,outer apply的表現要比子查詢好得多。 – FLICKER

+0

我沒有分析過性能,所以我不確定。但至少我們給了他/她不止一個選項。 :) –

+0

@BoydP謝謝!這工作完美無瑕。我的程序非常小,所以規模不會成爲問題,但閃爍,謝謝你的迴應。我甚至不知道到目前爲止存在交叉連接,而且我確實看到了您的編輯外部應用,所以我會看看是否可以稍後再開始工作,但現在這適合我的需求。感謝你們倆! – user3530169

1

您可以選擇的第一個電話,使用交叉聯接(沒有內部連接)像下面通用例子

select TC.*, pho.Phone, adr.[Address] 
from TContact AS TC 
    outer apply (select top 1 phone 
       from TContactPhoneNumbers 
       where ContactID = TC.ContactID) AS pho 
    outer apply (select top 1 [address] 
       from TContactAddresses 
       where ContactID = TC.ContactID) AS adr 
    outer apply (select top 1 [UserName] 
       from TUserContacts 
       where ContactID = TC.ContactID) AS uc 
    outer apply (select top 1 [UserName] 
       from TUsers 
       where UserId = uc.UserID) AS u 
where u.UserName = what ever ..... 

,並添加其他表,因爲你看到每一個聯繫人...

+0

這看起來正是我在找的東西,但where子句工作?我試圖使用'WHERE TContactPhoneNumbers.ContactID = TContacts.ContactID',但我不斷收到「多部分標識符TContacts.ContactID無法綁定」的錯誤。 – user3530169

+0

你是否在走私表格?如果你按照Flicker的建議「TContacts as tc」那麼你必須使用tc.ContactID,而不是TContacts.ContactID。 –

+0

@BoydP我確實嘗試過,都是TC。ContactID(與AS TC)和TContacts.ContactID(沒有AS TC)導致相同的錯誤。 – user3530169

相關問題