我有一個簡單的表格來存盤師生關系,以顯示學生在上課的班級或老師在教誰。無論哪種方式。(為了便于閱讀,按教師排序)
CREATE TABLE TS_RELATIONSHIP
(
Teacher NVARCHAR(10);
Student NVARCHAR(10);
)
例子:
Teacher Student
-------------------
Conner Yumi
Conner Shawn
Conner Casey
Ericson Eric
Ericson Yumi
Ericson Sue
Ericson Lin
Johnson Shawn
Johnson Lin
Johnson Ivan
Johnson Casey
Johnson Gina
現在,如果我有一組學生姓名,我怎樣才能找到資料的“完全匹配”?(順序無所謂)
例如,如果學生姓名的集合是Casey, Gina, Ivan, Lin, Shawn,那么我知道Johnson是我要找的老師,除了這五個人之外的任何其他人(正是這五個人,沒有一個學生短或更多),不會回傳任何內容(除非其他老師得到了完全匹配)。
我試圖在 C# 的幫助下做到這一點,并做了類似的事情,
string[] studentNames;
DataTable dt = SQL.GetDT(@"SELECT Teacher FROM [TS_RELATIONSHIP] WHERE Student=@p0;",studentNames[0]); //Assuming SQL.GetDT is a function that execute the T-SQL and return it as a DataTable.
for(int i=1;i<studentNames.Length;i )
{
string teacherNames = string.Join(",", dt.AsEnumerable().Select(x => string.Format($"'{x.Field<string>("Teacher")}'")));
dt=SQL.GetDT(@"SELECT Teacher FROM [TS_RELATIONSHIP] WHERE Student=@p0 and Teacher IN (@p1);",studentNames[i], teacherNames);
}
但是很快就會發現這個方法不會回傳一個“精確”的匹配!
只要教師“包含”學生串列,它就會作為答案回傳(這是不正確的)。
有人可以這么好心教我如何正確地做嗎?
無論是在純 T-SQL 中還是在 C# 的幫助下都可以。
非常感謝您的幫助!
uj5u.com熱心網友回復:
這是一個稱為無余數關系除法的問題。有多種解決方案。這是一個:
首先,您必須將所有值作為表傳遞給 SQL,為此您需要一個表值引數(如下所示的 C#)。
我將假設它TS_RELATIONSHIP在兩列中是唯一的,并且學生的輸入串列也是唯一的
SELECT
ts.Teacher
FROM TS_RELATIONSHIP ts
LEFT JOIN @students s ON s.Value = ts.Student
GROUP BY
ts.Teacher
HAVING COUNT(*) = @studentCount
AND COUNT(s.Value) = @studentCount;
這樣做是從表中取出所有行,將其左連接到輸入串列,將其分組Teacher并確保總行數等于輸入總數,并且匹配的輸入數也是正好等于那個總數。
您需要創建一個表型別,我通常會使用一些標準的單列型別:
CREATE TYPE dbo.StringList AS TABLE (Value nvarchar(250) NOT NULL PRIMARY KEY);
要將完整串列作為 TVP 傳遞,您可以執行以下操作:
var dtInput = new DataTable();
dtInput.Columns.Add("Value", typeof(string));
foreach (var student in studentNames)
dtInput.Rows.Add(student);
var dtResult = new DataTable();
using (var conn = new SqlConnection(yourConnString))
using (var comm = new SqlCommand("THE ABOVE QUERY"))
{
comm.Parameters.Add("@studentCount", SqlDbType.Int).Value = studentNames.Length;
comm.Parameters.Add(new SqlParameter("@students", SqlDbType.Structured) { TypeName = "dbo.StringList", Direction = ParameterDirection.Input, Value = dtInput});
conn.Open();
using (var reader = comm.ExecuteReader())
dtResult.Load(reader);
}
uj5u.com熱心網友回復:
這可能是一個解決方案:
給這個關系串列類
private class Nrelation
{
public string T;
public string S;
}
這應該作業
private string DOTest(List<string> match)
{
List<Nrelation> testList = new List<Nrelation>(); //<--Populate your relation data here
return testList.GroupBy(g => g.T).ToList()
.Where(item => isEqual(item.Select(x => x.S).ToList(), match))
.FirstOrDefault().Key;
}
private bool isEqual(List<string> list1, List<string> list2)
{
return Enumerable.SequenceEqual(list1.OrderBy(e => e), list2.OrderBy(e => e));
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/398061.html
下一篇:查找過去1小時內的重復資料
