C# C SQL在左联接中选择右表,只返回唯一的值,而不是每个值的一个实例

C# C SQL在左联接中选择右表,只返回唯一的值,而不是每个值的一个实例,c#,sql,datagridview,datasource,on-duplicate-key,C#,Sql,Datagridview,Datasource,On Duplicate Key,与以下方面合作: 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 AN

与以下方面合作:

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没有重复

如果我必须这样做,或者如果这样做更有效,我也愿意在以下情况之前从临时表中删除这些行:

        dgvQueryResult.DataSource = TempDS.Tables[0];
如果需要,或者如果最有效,请从dgvQueryResult中删除条目,而不是

左连接表2

尝试:


左连接Select id,locationId来自table2 group by id,locationId的count*=1作为table2

首先执行CTE以获取count>1的项目,然后添加到where子句以排除这些项目。我会给你SQL,但我必须去参加一个会议。如果你不熟悉如何创建一个通用表表达式CTE,你可以看看这个MSDN站点@Hogan,我确实尝试过,但不确定sytax,因为我在strSelect SQL的开头添加了任何形式的with,我得到了一个SqlException。我以前从未使用过CTE或Having Count*=1函数。而且找不到很多关于这个主题的优秀文档,尤其是在C中使用它时。@user2140261我经常在前面加一个分号,因为SQL Server喜欢抱怨它:;with@user2140261-Paul的回答很好,但这里有一个简单的例子>>使用ctename作为SELECT*FROM table SELECT*FROM CTENAMETH这完全符合我的预期这实际上与我头脑中的想法几乎相同,并且最初尝试过,不确定为什么我的不起作用,但效果很好。这与其他用户说要尝试的内容相比,CTE路线对我来说几乎是一样的。我相信这是一个偏好的问题。使用CTE应优化到完全相同的计划。当子查询变得更复杂时,我通常会发现CTE更具可读性,但在更琐碎的情况下使用子查询。