如何从所有列中仅选择一行,但第一行

时间:2016-04-22 22:59:22

标签: c# asp.net sql-server

这样的事情甚至可以吗?对于我尝试制作的应用程序,用户可以为单个联系人输入多个(或没有)电子邮件,电话号码和地址,但是在前面的页面上,我只想显示 每个联系人的电话号码,电子邮件地址和地址(如果有的话)。

这是我用于检索数据的SQL查询(请注意,为了便于阅读,我们稍微修改了它。实际上,我没有查询SQL的cookie。):

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>

这绝不是像这样的功能最优雅的实现,但就目前而言,我不是我使用的任何工具的专家。对此主题的任何帮助将不胜感激。

作为附录,如果有人碰巧知道如何在转换为HTML时显示的SQL SELECT语句中间添加换行符,那么组织FullAddress将非常有用。 CHAR(10) + CHAR(13)看似没有任何价值。

2 个答案:

答案 0 :(得分: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"]

或者,使用&#34;默认&#34;表中的布尔值,让用户输入数据保存其默认地址,电话号码等

答案 1 :(得分: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 .....

并添加其他表格,如您所见......