2013-06-20 4 views
0

[풀이], gzaxx 님의 답변입니다.데이터 격자에 동일한 데이터 두 개를 표시합니다.

데이터베이스에서 멤버가 두 번 삽입되지 않더라도 데이터 그리드에서 두 번 표시됩니다! 회원을 추가하는이 양식과 회원 지불을 추가하는 양식이 있습니다. 한 회원에게 2 회 이상 지불 할 때 그 회원은 그리드에 2 번을 보여줍니다.

내가이 사용하고 구성원을 나열하는 방법 :

 public List<Member> ListMembers() 
     { 
      List<Member> Members = new List<Member>(); 


      string STATUS = "SELECT m.Id, m.Name,m.Surname, m.EntryDate, p.EndDay FROM Members m left join Payments p on m.Id = p.MemberId order by m.Id "; 
      using (sqlConnection = new SqlConnection(sqlConnectionString_WORK)) 
      { 
       sqlConnection.Open(); 

       using (SqlCommand sqlCommand = new SqlCommand(STATUS, sqlConnection)) 
       { 
        var sqlReader = sqlCommand.ExecuteReader(); 

        while (sqlReader.Read()) 
        { 
         var member = new Member 
         { 
          Id = Convert.ToInt32(sqlReader["Id"]), 
          Name = sqlReader["Name"].ToString(), 
          Surname = sqlReader["Surname"].ToString(), 
          EntryDate = Convert.ToDateTime(sqlReader["EntryDate"]) 
         }; 

         if (sqlReader["EndDay"].ToString() != "") 
         if (Convert.ToDateTime(sqlReader["EndDay"]) < DateTime.Today) 
         { 
          member.Status = Status.Unpaid.ToString(); 
         } 

         else 
         { 
          member.Status = Status.Paid.ToString(); 
         } 

         Members.Add(member); 
        } 
       } 
      } 

      return Members; 
     } 

지불의 경우 : 회원이 지불이없는

 public List<Payment> ListPayments(Payment entity) 
     { 
      List<Payment> Payments = new List<Payment>(); 

      string SELECT = "SELECT * FROM Payments WHERE MemberId = @MemberId"; 

      using (sqlConnection = new SqlConnection(sqlConnectionString_WORK)) 
      { 
       sqlConnection.Open(); 

       using (SqlCommand sqlCommand = new SqlCommand(SELECT, sqlConnection)) 
       { 
        sqlCommand.Parameters.Add("@MemberId", SqlDbType.Int).Value = entity.MemberId; 

        var sqlReader = sqlCommand.ExecuteReader(); 

        while (sqlReader.Read()) 
        { 
         var payment = new Payment 
         { 
          Id = Convert.ToInt32(sqlReader["Id"]), 
          MemberId = Convert.ToInt32(sqlReader["MemberId"]), 
          Amount = Convert.ToDecimal(sqlReader["Amount"]), 
          StartDay = Convert.ToDateTime(sqlReader["StartDay"]), 
          EndDay = Convert.ToDateTime(sqlReader["EndDay"]) 
         }; 

         Payments.Add(payment); 
        } 
       } 
      } 

      return Payments; 
     } 

경우는 상태 열입니다, 그것은 아무것도 표시되지 않습니다. 회원이 한 번 지불하면 상태가 표시됩니다. 그러나 새로운 지불 (하나 이상)을 추가하면 데이터 그리드는 동일한 회원을 그리드 지불과 동일하게 표시합니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까 ???

답변

1

이 쿼리 :

SELECT m.Id, m.Name,m.Surname, m.EntryDate, p.EndDay FROM Members m left join Payments p on m.Id = p.MemberId order by m.Id 

주어진 멤버와 일치 (찾을 경우) 모든 Payment.EndDay 기록과 멤버를 반환합니다. 따라서 한 행만 (최신 결제일 경우) 검색어를 입력하면 검색어는 다음과 같이 표시됩니다.

SELECT m.Id, m.Name,m.Surname, m.EntryDate, MAX(p.EndDay) as EndDay 
FROM Members m left join Payments p on m.Id = p.MemberId 
GROUP BY m.Id, m.Name,m.Surname, m.EntryDate 
order by m.Id 
+0

이것은 한 명의 회원만을 보여주기 때문에 수정되었습니다. 그러나 최종 지불금을받지 못합니다. : \ – Etrit

+0

최신 'EndDay'를 얻습니다. 최신 Payemnt가 'EndDay' 최신판과 같은가요? – gzaxx

+0

오, 괜찮아! 나는 내가 등록하고있는 날짜보다 더 큰 날짜가 이미 있는지를 확인하지 않고 있었다. 그것은 완벽하게 작동합니다. 고맙습니다 :) – Etrit

0

왼쪽 가입 방식은 작동 방식입니다. http://www.w3schools.com/sql/sql_join_left.asp

값이 두 배가되는 것은 "조인"때문입니다. 지불하는만큼의 레코드가 반환됩니다. @ gzaxx 제안은 좋은 생각 일 수 있습니다.

사용중인 데이터베이스에 따라 지불이없는 열에 null이 있으면 ISNULL (mssql) (http://www.w3schools.com/sql/sql_isnull.asp) 명령을 사용하여 해결할 수 있습니다. 당신의 질문.

관련 문제