如何显示具有多对多关系的SQL Server数据库记录
本文关键字:关系 Server 记录 数据库 SQL 何显示 显示 | 更新日期: 2023-09-27 17:49:13
我正在使用ASP。. NET c#从SQL Server数据库查询输出结果,并尝试让结果在每个球场只显示一条记录,但也在每个球场显示多个联系人详细信息。
相关表为(PK为粗体,FK为斜体):
法院(Court_ID, Court_Name,笔记,城镇,邮政编码)
通讯录(Contact_ID, Contacts_Name, Contacts_no, *Court_ID*, *Court_Contact_Type_ID*)
Contact_Type (Court_Contact_Type_ID, Court_Contact_Type_Desc)
目前我的问题是,每个球场有多少联系人,我就会得到每个球场细节的多次重复。我知道它为什么这样做,但我不知道如何使它按我想要的方式工作。
我不确定解决方案是否存在于SQL查询本身(可能通过嵌套解决…?)或c#代码,因为我使用'HasRows'。我在下面包含了这两个代码片段。
string myQuery = "SELECT Court_Name, Town, Postcode, Note, Contacts_Name, Contacts_no, Court_Contact_Type_Desc " +
"FROM Court C, Contacts CON, Contact_type CONT " +
"WHERE C.Court_ID = CON.Court_ID AND CON.Court_Contact_Type_ID = CONT.Court_Contact_Type_ID AND C.Court_ID = '3' ";
SqlConnection connection = new SqlConnection(connStr);
SqlCommand myCommand = new SqlCommand(myQuery, connection);
SqlDataReader myDataReader;
connection.Open();
myDataReader = myCommand.ExecuteReader();
if (myDataReader.HasRows)
{
while (myDataReader.Read())
{
string court_name = myDataReader["Court_Name"].ToString();
string court_town = myDataReader["Town"].ToString();
string court_pcode = myDataReader["Postcode"].ToString();
string court_note = myDataReader["Note"].ToString();
string court_contact_name = myDataReader["Contacts_Name"].ToString();
string court_contact_desc = myDataReader["Court_Contact_Type_Desc"].ToString();
string court_contacts_no = myDataReader["Contacts_no"].ToString();
Response.Write("<strong>" + court_name + "</strong><br>" + court_town + "<br>" + court_pcode + "<p>" + court_note + "</p>" + "<p>" + court_contact_name + " - " + court_contact_desc + " : " + court_contacts_no + "</p>");
}
}
最终的输出应该看起来像这样:
阿伯加文尼裁判法院
Abergavenny
NP7 5 dl
本庭只供聆讯。附加法庭记录....
联系人姓名1 -代理法院经理:01633 64xxxx
联系人姓名2 -代理办公室经理:01633 64xxxx
联系人姓名3 -代理名单主任:01633 64xxxx
联系人姓名4 -大法官书记:01633 64xxxx
一如既往地感谢您的帮助!
欢呼
你可以这样解决这个问题:
- 将court_id添加到选择列表
- 添加排序标准,将属于同一法院的行放在彼此旁边
- 当迭代返回的数据时,查看您之前是否看到过court id
- 如果这是您第一次看到法院id,请同时显示法院和联系方式
- 如果你以前见过这个法庭id,只显示联系信息
下面是一个例子:
string myQuery = "SELECT C.Court_ID, Court_Name, Town, Postcode, Note, Contacts_Name, Contacts_no, Court_Contact_Type_Desc " +
"FROM Court C "+
"JOIN Contacts CON ON C.Court_ID = CON.Court_ID "+
"JOIN Contact_type CONT ON CON.Court_Contact_Type_ID = CONT.Court_Contact_Type_ID " +
"WHERE C.Court_ID = '3' "+ // I assume the search criteria will be different
"ORDER BY C.Court_ID"; // Very important: records for the same court must be together
...
string last_id = string.Empty;
while (myDataReader.Read())
{
string court_id = myDataReader["Court_ID"].ToString();
string court_name = myDataReader["Court_Name"].ToString();
string court_town = myDataReader["Town"].ToString();
string court_pcode = myDataReader["Postcode"].ToString();
string court_note = myDataReader["Note"].ToString();
string court_contact_name = myDataReader["Contacts_Name"].ToString();
string court_contact_desc = myDataReader["Court_Contact_Type_Desc"].ToString();
string court_contacts_no = myDataReader["Contacts_no"].ToString();
if (last_id != court_id) {
// Write court AND contact
Response.Write("<strong>" + court_name + "</strong><br>" + court_town + "<br>" + court_pcode + "<p>" + court_note + "</p>" + "<p>" + court_contact_name + " - " + court_contact_desc + " : " + court_contacts_no + "</p>");
} else {
// Write only contact
Response.Write("<p>" + court_contact_name + " - " + court_contact_desc + " : " + court_contacts_no + "</p>");
}
last_id = court_id;
}
你可能想试试这个(如果我得到正确的你想要显示)。假定触点和触点类型为1:1链路。
SELECT Court_Name, Town, Postcode, Note, contacts
from Court
where Court_ID = '3'
CROSS APPLY
(
select substring((
SELECT ',' + Contact_Name+ ' ' +Contacts_no + ' ' + Court_Contact_Type_Desc
FROM Contacts join Contact_Type on Contacts.Court_Contact_Type_ID = Contact_Type.Court_Contact_Type_ID
WHERE Contacts.CourtID = Court.CourtID
FOR XML PATH('')
),2,1000)
as Contacts
) contacts
最直接的方法是将其拆分为2个查询。
第一个查询:获取指定Id的法院。
第二个查询:获取具有指定Id的法院的联系人列表。
好的一面是它使事情简单易懂。而且,如果没有找到联系人(我不知道这种可能性有多大),您仍然可以输出正确的法院地址。
缺点是您对数据库执行了两个SQL查询。这可能是性能方面的考虑。
注意:如果你通过连接字符串来进行SQL查询,就像你的例子一样…小心SQL注入攻击!参见:SQL注入和参数化查询