2013-03-15 51 views
1

不是一個實例具有以下工作:C#SQL選擇右表在左聯接僅返回唯一值,每個

string strSelectSql = "SELECT Table1.ID, Table1.Status, 
    Table1.CustomerName,Table1.Date, Table1.LocationID, 
    Table2.LocationID As [LocationID 2] FROM Table1 LEFT JOIN 
    Table2 ON Table1.ID = Table2.ID 
    WHERE (Date Is Null AND ID= @SearchForString AND 
    Status != 'Archived') OR 
    ((Date Between @FromDate AND @ToDate) 
    AND ID= @SearchForString AND Status != 'Archived')"; 

     SqlConnection SqlConn = new SqlConnection(cstrDatabaseConnection); 
     SqlDataAdapter SqlAdpt = new SqlDataAdapter(); 
     SqlCommand SqlCom = new SqlCommand(strSelectSql,SqlConn); 
     SqlCom.Parameters.AddWithValue("@SearchForString",strSearchString); 
     SqlCom.Parameters.AddWithValue("@FromDate",strFromDate); 
     SqlCom.Parameters.AddWithValue("@ToDate",strToDate); 

     SqlAdpt.SelectCommand = SqlCom; 
     try 
     { 
      DataSet TempDS = new DataSet(); 
      SqlConn.Open(); 
      SqlAdpt.Fill(TempDS); 
      SqlConn.Close(); 
      SqlConn.Dispose(); 
      if (Convert.ToInt32(TempDS.Tables[0].Rows.Count) > 0) 
      { 
       dgvQueryResult.DataSource = TempDS.Tables[0]; 
       dgvQueryResult.Refresh(); 
       dgvQueryResult.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells); 
       TempDS.Dispose(); 
      } 

     } 
     catch (SqlException sqlE) 
     { 
      MessageBox.Show(sqlE.Message); 
      SqlConn.Close(); 
      SqlConn.Dispose(); 
     } 
     catch (Exception UnknownE) 
     { 
      MessageBox.Show(string.Format("Unknown Exception: {0}",UnknownE.Message); 
      SqlConn.Close(); 
      SqlConn.Dispose(); 
     } 
     finally 
     { 
      if (SqlConn != null) SqlConn.Dispose(); 
     } 

現在,這一切工作正常,很正常,除非表2對LocationID

多個值
Table2 
+----+------------+ 
| ID | LocationID | 
+----+------------+ 
| 1 |  1  | 
| 2 |  2  | 
| 3 |  3  | 
| 4 |  4  | 
| 5 |  5  | 
| 6 |  6  | 
| 6 |  7  | 
| 6 |  7  | 
| 7 |  8  | 
| 7 |  9  | 
+----+------------+ 

我想忽略:

Table2 
+----+------------+ 
| ID | LocationID | 
+----+------------+ 
| 6 |  7  | 
| 6 |  7  | 
+----+------------+ 

,並得到這個:

Table2 
+----+------------+ 
| ID | LocationID | 
+----+------------+ 
| 1 |  1  | 
| 2 |  2  | 
| 3 |  3  | 
| 4 |  4  | 
| 5 |  5  | 
| 6 |  6  | 
| 7 |  8  | 
| 7 |  9  | 
+----+------------+ 

但我想:

Table2 
+----+------------+ 
| ID | LocationID | 
+----+------------+ 
| 6 |  6  | 
+----+------------+ 

因爲LocationID不重複。

另外,我想:

Table2 
+----+------------+ 
| ID | LocationID | 
+----+------------+ 
| 7 |  8  | 
| 7 |  9  | 
+----+------------+ 

再次因爲LocationID不重複。

如果非要或是否會更有效率我也願意之前刪除從TempDS這些行:

 dgvQueryResult.DataSource = TempDS.Tables[0]; 

如果連必要時,或者最有效的直接從dgvQueryResult

刪除條目而不是
+0

首先執行CTE以獲取計數大於1的項目,然後將其添加到where子句以排除這些項目。我會給你SQL,但我必須去開會。 – Hogan 2013-03-15 16:14:49

+0

如果您不熟悉如何創建公用表達式(CTE),可以查看此MSDN網站[CTE SQL Server](http://msdn.microsoft.com/zh-cn/library/ms190766(v = sql.105).aspx) – MethodMan 2013-03-15 16:19:50

+0

@Hogan我曾嘗試過,但不確定的sytax,因爲我在strSelectSql的開頭添加了任何形式的WITH我得到了一個SqlException。我以前從來沒有使用過CTE或之前有Having Count(*)= 1的函數。而且在這個主題上找不到很多很棒的文檔,尤其是在C#中使用它時。 – user2140261 2013-03-15 16:21:29

回答

3

LEFT JOIN Table2

嘗試:

LEFT JOIN (Select id, locationId from table2 group by id, locationId having count(*) = 1) as table2

+0

這和我預期的完全一樣,這實際上和我腦海中所做的嘗試幾乎完全相同,不知道爲什麼我的工作不成功,但是這很好。這與其他用戶說什麼嘗試,CTE路線相比,它們看起來與我差不多。 – user2140261 2013-03-15 16:33:54

+0

我認爲這是一個偏好問題。使用CTE應該優化到完全相同的計劃。當子查詢變得更加複雜時,我會更好地發現CTE更可讀,但是使用子查詢處理更瑣碎的情況。 – paul 2013-03-15 16:38:21