C# 处理多个一对多关系并只输出一次结果的单个SQL查询

C# 处理多个一对多关系并只输出一次结果的单个SQL查询,c#,asp.net,sql-server,C#,Asp.net,Sql Server,我有3个数据库表,它们之间有2个完全独立的一对多关系,我很难编写一个SQL查询来输出每个相关信息的单个记录 也许,最后,由于这两个关系是分开的,这意味着我需要编写两个单独的连接和SQL查询,但我想我还是会问,希望有人已经解决了类似的问题(在解决这个问题时,我可以将相同的原则应用于整个数据库中出现的其他单独的一对多关系,并且可以“理想地”创建一个大型查询,而不是更多单独的连接/查询) 到目前为止,我的问题是: SELECT C.court_id, court_email_desc, court_e

我有3个数据库表,它们之间有2个完全独立的一对多关系,我很难编写一个SQL查询来输出每个相关信息的单个记录

也许,最后,由于这两个关系是分开的,这意味着我需要编写两个单独的连接和SQL查询,但我想我还是会问,希望有人已经解决了类似的问题(在解决这个问题时,我可以将相同的原则应用于整个数据库中出现的其他单独的一对多关系,并且可以“理想地”创建一个大型查询,而不是更多单独的连接/查询)

到目前为止,我的问题是:

SELECT C.court_id, court_email_desc, court_email_addr, court_opening_type_desc, court_opening_desc
FROM court C
JOIN court_email CE ON C.court_id = CE.court_id
JOIN court_opening CO ON C.court_id = CO.court_id
JOIN court_opening_type COT ON CO.court_opening_type_id = COT.court_opening_type_id
WHERE C.court_id = '" + court_id_no + "'
ORDER BY C.court_id
其输出的内容大致如下:

查询:enquiries@enquiries.email
法院大楼开放时间:上午8时30分

执达主任:bailiffs@bailiffs.email
法院大楼开放时间:上午8时30分

听证会:hearings@hearings.email
法院大楼开放时间:上午8时30分

提交电子文件:CCMCE-filing@filing.email
法院大楼开放时间:上午8时30分

公众查询电邮:ccmcccustomerenquiries@pubenq.email
法院大楼开放时间:上午8时30分

查询:enquiries@enquiries.email
法院大楼关闭时间:下午5时

执达主任:bailiffs@bailiffs.email
法院大楼关闭时间:下午5时

等等(NB:电子邮件地址重复4次,每种类型的开场白一次)

所需的输出将如下所示:

查询:enquiries@enquiries.email
执达主任:bailiffs@bailiffs.email
听证会:hearings@hearings.email
提交电子文件:CCMCE-filing@filing.email
公众查询电邮:ccmcccustomerenquiries@pubenq.email

法院大楼开放时间:上午8:30
法院大楼关闭时间:下午5:00
电话查询:上午9:00
电话查询至:下午5:00

有没有一种方法可以巧妙地嵌套查询,以便在我选择显示的任何法庭上只输出一次每个电子邮件地址和开场类型/时间?这在SQL查询中是否可行,或者在我输出结果时,聪明的部分是否会出现在C中

我的C#代码目前如下:

myDataReader3 = myCommand3.ExecuteReader();

        if (myDataReader3.HasRows) {

            string last_id = string.Empty;
            string last_id2 = string.Empty;

            while (myDataReader3.Read()) {

                string court_id = myDataReader3["court_id"].ToString();
                string court_email_desc = myDataReader3["court_email_desc"].ToString();
                string court_email_addr = myDataReader3["court_email_addr"].ToString();
                string court_opening = myDataReader3["court_opening_desc"].ToString();
                string court_opening_type = myDataReader3["court_opening_type_desc"].ToString();

                if (last_id != court_id) {

                    Response.Write("<br><strong>Email address</strong><br>" + court_email_desc + ": " + court_email_addr + "<br>");

                } else {

                    Response.Write(court_email_desc + ": " + court_email_addr + "<br>");

                }

                last_id = court_id;

                if (last_id2 != court_id) {

                    Response.Write("<br><strong>Opening times</strong><br>" + court_opening_type + ": " + court_opening + "<br>");

                } else {

                    Response.Write(court_opening_type + ": " + court_opening + "<br>");

                }

                last_id2 = court_id;

            }

        }
myDataReader3=myCommand3.ExecuteReader();
if(myDataReader3.HasRows){
string last_id=string.Empty;
string last_id2=string.Empty;
while(myDataReader3.Read()){
字符串court_id=myDataReader3[“court_id”].ToString();
字符串court_email_desc=myDataReader3[“court_email_desc”]。ToString();
字符串court_email_addr=myDataReader3[“court_email_addr”]。ToString();
字符串court_opening=myDataReader3[“court_opening_desc”]。ToString();
字符串court_opening_type=myDataReader3[“court_opening_type_desc”]。ToString();
如果(最后一个id!=法庭id){
回复。写(“
电子邮件地址“+court\u Email\u desc+”:“+court\u Email\u addr+”
”; }否则{ 回复。书写(court\u email\u desc+“:“+court\u email\u addr+”
”; } 最后一个id=法庭id; 如果(最后一个id!=法庭id){ 回答。写(“
开放时间”
“+court\u Opening\u type+”:“+court\u Opening+”
”; }否则{ 回答。写下(庭审开场类型+”:“+庭审开场+”
”; } last_id2=法庭id; } }

提前感谢您的时间和我得到的任何帮助。

您应该能够将
行号()over()
添加到SQL查询中,然后应用
CASE
语句:

select court_id,
  court_email_desc,
  case when rn=1 then court_email_addr else '' end court_email_addr,
  court_opening_type_desc,
  court_opening_desc
from
(
  SELECT C.court_id, 
    court_email_desc, 
    court_email_addr, 
    court_opening_type_desc, 
    court_opening_desc,
    row_number() over(partition by c.court_id order by c.court_id) rn
  FROM court C
  JOIN court_email CE 
    ON C.court_id = CE.court_id
  JOIN court_opening CO 
    ON C.court_id = CO.court_id
  JOIN court_opening_type COT 
    ON CO.court_opening_type_id = COT.court_opening_type_id
  WHERE C.court_id = '" + court_id_no + "'
) src
order by court_id
这是在原始查询中添加一个
row\u number()
,通过
court\u id
。然后将
CASE
语句应用于返回的字段,检查
row\u number
是否等于1。如果等于1,则显示列的值。如果不是,则显示空字符串

编辑#1:如果您只希望
打开
关闭
值出现一次,您还可以
透视
类似以下内容的数据:

SELECT c.court_id, 
  court_email_desc, 
  court_email_addr, 
  max(case when court_opening_type_desc = 'Court building open' then court_opening_desc end) Opens,
  max(case when court_opening_type_desc = 'Court building closed' then court_opening_desc end) Closes
FROM court C
JOIN court_email CE 
  ON C.court_id = CE.court_id
JOIN court_opening CO 
  ON C.court_id = CO.court_id
JOIN court_opening_type COT 
  ON CO.court_opening_type_id = COT.court_opening_type_id
WHERE C.court_id = '" + court_id_no + "'
group by c.court_id, court_email_desc, court_email_addr;
编辑#2:如果不使用单独的查询,我的最后一个建议是将
行编号()
PIVOT
实现为单个解决方案:

SELECT court_id, 
  court_email_desc, 
  court_email_addr, 
  max(case when court_opening_type_desc = 'Court building open' and rn=1 then court_opening_desc end) CourtOpens,
  max(case when court_opening_type_desc = 'Court building closed' and rn=1 then court_opening_desc end) CourtCloses
FROM
(
    SELECT c.court_id, 
        court_email_desc, 
        court_email_addr, 
        court_opening_type_desc, 
        court_opening_desc,
        row_number() over(partition by c.court_id, court_opening_type_desc order by court_email_desc) rn
    FROM court C
    JOIN court_email CE 
      ON C.court_id = CE.court_id
    JOIN court_opening CO 
      ON C.court_id = CO.court_id
    JOIN court_opening_type COT 
      ON CO.court_opening_type_id = COT.court_opening_type_id
    WHERE C.court_id = '" + court_id_no + "'
) src
group by court_id, court_email_desc, court_email_addr;
查询中的数据应显示为:

court_id    | court_email_desc          | court_email_addr                      | CourtOpens    | CourtCloses
------------------------------------------------------------------------------------------------------------------------
1           | Bailiffs                  | bailiffs@bailiffs.email               | 8:30am        | 5:00pm
1           | Public Enquiries Email    | ccmcccustomerenquiries@pubenq.email   |               |
1           | Filing e-documents        | ccmcce-filing@filing.email            |               |
1           | Enquiries                 | enquiries@enquiries.email             |               |
1           | Hearings                  | hearings@hearings.email               |               |

感谢您的回复,但是上面的内容似乎不起作用。我已经在SQL Server中直接运行了查询(稍后我将处理C)除了现在输出的唯一法庭电子邮件地址是第一行之外,其他所有的都是空白。仍然有“开始类型”和“开始描述”的重复记录。@DanSolo你能发布查询的预期结果吗?显然我在你的要求中遗漏了一些内容。请参阅我的编辑有一个替代版本,该版本将以打开/关闭值为轴心,每个部门/电子邮件等只剩下一行,事后看来,输出显示得不太好,我想要的输出显然完全丢失了-您可能会看到,您上次的编辑没有多大帮助(抱歉).根据我上面的编辑,我是否完全用SQL查询和我希望它如何输出的方法弄错了树?正如我所说的,我不确定到底是两个查询更好,还是C#?@DanSolo中的另一个输出方法。请查看我的编辑,以获得一个可能的解决方案,该解决方案不会涉及两个查询。感谢您的所有时间和努力。同时,您r new edit完全按照您的预测进行,在反思时,我不确定以这种方式将列链接到fin会获得多少价值