2

私は3つのデータベーステーブルを持っており、それらの間に2つの完全に独立した1対多の関係があり、関連する情報ごとに1つのレコードを出力する単一のSQLクエリを書くのが非常に困難です。

結局のところ、2 つの関係は別のものなので、2 つの別々の接続と SQL クエリを記述する必要があることを意味しますが、誰かが同様の問題を抱えて解決したことを無駄に期待して、とにかく尋ねたいと思いました (これを解決するために、データベース全体で発生する他の個別の1対多の関係に同じ原則を適用し、さらに個別の接続/クエリではなく、「理想的には」1つの大きなクエリを作成できます)。

私がこれまでに持っているクエリは次のとおりです。

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 分

電子書類の提出 : ccmcce-filing@filing.email
裁判所の開館時間 : 午前 8 時 30 分

公開のお問い合わせ Eメール : ccmcccustomerenquiries@pubenq.email
裁判所の開館時間 : 午前8時30分

お問い合わせ : enquiries@enquiries.email
裁判所の建物閉鎖 : 午後 5 時

廷吏 : bailiffs@bailiffs.email
裁判所の建物閉鎖 : 午後 5 時

など.... (注:メールアドレスは、冒頭の説明の種類ごとに 1 回ずつ、合計 4 回繰り返されます)

望ましい出力は次のようになります。

お問い合わせ : enquiries@enquiries.email
執行官 : bailiffs@bailiffs.email
公聴会 : hearings@hearings.email
電子書類の提出 : ccmcce-filing@filing.email
公開のお問い合わせ Eメール : ccmcccustomerenquiries@pubenq.email

裁判所開庁 : 午前 8 時 30 分
裁判所庁舎閉鎖 : 午後 5 時
電話でのお問い合わせ : 午前 9 時から 電話でのお問い合わせ :午後 5 時
まで

クエリを巧みにネストして、表示することを選択した裁判所に対して、各メールアドレスとオープニングの種類/時間を一度だけ出力する方法はありますか? これは 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;

            }

        }

お時間を割いていただき、ありがとうございます。

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フィールドにステートメントを適用して、 が 1 に等しいかどうかをチェックrow_numberします。1 に等しい場合は、列の値を表示します。そうでない場合は、空の文字列が表示されます。

編集 #1:Openとのclosed値を 1 回だけ表示する場合は、次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()andPIVOTを単一のソリューションに実装することです。

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 に答える