我有一个网站,显示有关可用讲座的信息。每个讲座都有一个标题,一个相关的演讲者,以及(可能)多个类别。数据库模式看起来像这样(警告:这是空中代码,因为我没有在我面前有数据库)...
create table Lectures (
ID int not null identity(1,1) primary key,
Title varchar(max) not null default '',
SpeakerID int not null foreign key references Speakers(ID)
)
create table Categories (
ID int not null identity(1,1) primary key,
Name varchar(max) not null default ''
)
create table Lectures_Categories (
ID int not null identity(1,1) primary key,
LectureID int not null foreign key references Lectures(ID),
CategoryID int not null foreign key references Categories(ID)
)
在查看有关讲座的详细信息时,我希望能够推荐相关讲座,但我不确定如何编写这个。我最初的想法是,以下标准将用于计算相关性(最重要的是第一个)...
如果根据上述标准对两个讲座进行同等排名,我希望将较新的讲座排在旧标准之上。
任何人都知道如何编写这个?我在C#中执行此操作,如果任何相关的SQL Server数据库使用实体框架模型。
答案 0 :(得分:1)
让我理解基本思路:假设所有三个条件都可以在sql查询中表达,那么你应该得到加权结果集,然后你union
一起。
第一个只是select ID, 10 as weight from lectures where ID <> ourLectureID and speakerID = ourSpeakerID
第二个是join
超过Lectures
和Topics
,权重较小,可能是4
。
现在让我们忽略第三个查询的问题。
现在我们已经设置了result1
个ID和权重,我们就组了一个组&amp;和。我的sql今天相当生疏,但我想的是这样的事情:select max(ID), sum(weight) as ranking from result1 group by ID order by ranking
..完成!
现在我已经差不多20年没碰过SQL服务器了;-)但是我觉得它不适合创建第三个查询。数据库设计师只会给你一个有趣的外观,并告诉你查询标题是糟糕的坏事;并且'为什么你没有添加keywords
表.. ??
如果您不想这样做,我认为您可以将所有标题提取到C#应用程序中并使用其字符串/集合/ LINQ功能过滤掉有趣的单词并使用第三个排名创建第三个查询;也许只有4个字母以上的大写字母..?
<强>更新强>
以下是如何在一系列行中找到最佳拟合线的一个很小的例子:
List<string> proverbs = new List<string>();
List<string> cleanverbs = new List<string>();
List<string> noverbs = new List<string>();
private void button1_Click(object sender, EventArgs e)
{
noverbs.AddRange(new[] { "A", "a", "by", "of", "all", "the", "The",
"it's", "it", "in", "on", "is", "not", "will", "has", "can", "under" });
proverbs = File.ReadLines("D:\\proverbs\\proverbs.txt").ToList();
cleanverbs = proverbs.Select(x => cleanedLine(x)).ToList();
listBox1.Items.AddRange(proverbs.ToArray());
listBox2.Items.AddRange(cleanverbs.ToArray());
}
string cleanedLine(string line)
{
var words = line.Split(' ');
return String.Join(" ", words.ToList().Except(noverbs) );
}
int countHits(string line, List<string> keys)
{
var words = line.Split(' ').ToList();
return keys.Count(x => words.Contains(x));
}
private void listBox2_SelectedIndexChanged(object sender, EventArgs e)
{
string line = listBox2.SelectedItem.ToString();
int max = 0;
foreach (string proverb in cleanverbs)
{
var keys = proverb.Split(' ').ToList();
int count = countHits(line, keys);
if (count > max && proverb != line)
{
max = count;
Text = proverb + " has " + max + " hits";
}
}
}
它使用了两个列表框和一个谚语的文本文件。加载后,您可以单击第二个列表框,窗口标题将显示点击次数最多的行。
您需要进行一些更改: