2

I have 3 database tables that have between them 2 totally separate one-to-many relationships and I'm having great difficulty in writing a single SQL query to output a single record for each relevant piece of information.

Maybe, in the end, as the 2 relationships are separate it means I'll need to write 2 separate connections and SQL queries but I thought I'd ask anyway in the vain hope that someone out there has had and solved a similar issue (and in solving this I could then apply the same principle to other separate one-to-many relationships that occur throughout the database and could 'ideally' create one large query rather than even more separate connections/queries).

The query I have so far is:

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

which outputs something along the lines of:

Enquiries : enquiries@enquiries.email
Court building open : 8.30 am

Bailiffs : bailiffs@bailiffs.email
Court building open : 8.30 am

Hearings : hearings@hearings.email
Court building open : 8.30 am

Filing e-documents : ccmcce-filing@filing.email
Court building open : 8.30 am

Public Enquiries Email : ccmcccustomerenquiries@pubenq.email
Court building open : 8.30 am

Enquiries : enquiries@enquiries.email
Court building closed : 5.00 pm

Bailiffs : bailiffs@bailiffs.email
Court building closed : 5.00 pm

etc.... (NB: the email addresses are repeated 4 times, once for each type of opening desc)

The desired output would be something like this:

Enquiries : enquiries@enquiries.email
Bailiffs : bailiffs@bailiffs.email
Hearings : hearings@hearings.email
Filing e-documents : ccmcce-filing@filing.email
Public Enquiries Email : ccmcccustomerenquiries@pubenq.email

Court building open : 8.30 am
Court building closed : 5.00 pm
Telephone Enquiries from : 9.00am
Telephone Enquiries until : 5.00pm

Is there a way I can cleverly nest the query to output each email address and opening type/time only once for whichever court I choose to display? Would this even be possible in the SQL query or would the clever bit come in the C# when I output the results?

My C# code currently stands as below:

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;

            }

        }

Thanks in advance for your time and any help that comes my way.

4

1 回答 1

1

您应该能够添加row_number() 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_number()在原始查询中添加 a 和 by court_id。然后将CASE语句应用于要返回的字段,检查是否row_number等于 1。如果是,那么您将显示该列的值。如果不是,那么它将显示一个空字符串。

编辑#1:如果您只希望Openandclosed值出现一次,您也可以PIVOT使用与此类似的数据:

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:如果您不使用单独的查询,我的最终建议是将row_number()and实现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               |               |
于 2013-01-03T12:13:45.287 回答