65.9K
CodeProject 正在变化。 阅读更多。
Home

如何为 SQL 创建基于相关性的搜索查询

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.75/5 (4投票s)

2010年12月31日

CPOL

3分钟阅读

viewsIcon

40237

downloadIcon

359

排列结果以获得最相关的结果优先...

引言

很多时候,我们需要在应用程序中实现搜索算法。因此,在正常情况下,我们可能会搜索各种条件下的术语,然后找到与搜索查询的最佳匹配项。我也想要做同样的事情,我想为我的应用程序搜索汽车。在我的应用程序中,我想要五个标准,即刹车、燃油、锁、引擎和转向。因此,客户将从组合框中选择选项(仅来自列的有效值),然后显示匹配最多特征的汽车。

背景

为了实现本文,您必须了解 UNIONORDER BYGROUP BY 子句的操作以及 VB.NET 中的数据库连接。

Using the Code

我们将学习两个部分

  1. 如何将列加载到组合框中,以便用户只能选择有效值
  2. 如何创建搜索以获得最佳结果

从这里开始,我有一小段代码片段。我只是将代码实现为逻辑。我们有五个组合框,用户将从中选择值,然后通过搜索加载这些值。

Dim connObj As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _
	Application.StartupPath & "\Car_Showroom.mdb")
Dim commObj As New OleDbCommand
Dim myDataReader As OleDbDataReader
Dim myDataSet, myDataSet1 As New DataSet
Dim query(3) As String
Dim myAdapter As OleDbDataAdapter

这些是数据库连接对象。以下是加载具有该特定列的单个组合框的代码。

  myDataSet1.Clear()
        connObj.Open()
        ''''''' Load Steering
        myDataSet1.Clear() ' clear all the values from Data Set if any
        cmbSteering.Items.Clear() ' clear all the items of the Combo BOx
        commObj = New OleDbCommand("SELECT DISTINCT Steering _
	FROM CarDetails", connObj) ' Create a command object and add connection
        myAdapter = New OleDbDataAdapter(commObj)
        myAdapter.Fill(myDataSet1, "cDetails") ' Execute the Query and 
					' fill the results in the dataset.
        cmbSteering.Text = "Select Company
' This is the most important code
For Each ds As DataRow In myDataSet1.Tables("cDetails").Rows 
            cmbSteering.Items.Add(ds("Steering").ToString())
        Next 

上述代码的解释

我们正在创建一个 DataRow 对象,然后使用 For Each 循环将转向列值添加到组合框中。

这是该部分的下一部分。我在互联网上搜索过这个,但没有找到一个。所以我努力工作并将其弄清楚作为解决方案之一。

以下显示 SQL 查询及其解释

 Dim steer As String = cmbSteering.SelectedItem
        Dim engine As String = cmbEngine.SelectedItem
        Dim fuel As String = cmbFuel.SelectedItem
        Dim lock As String = cmbLock.SelectedItem
        Dim brakes As String = cmbBrakes.SelectedItem
        myDataSet.Clear()
        connObj.Open()
        query(1) = "SELECT PRODID,Occurence FROM (SELECT ProdId,count(*) _
		AS Occurence FROM (SELECT ProdId FROM CarDetails WHERE _
		Steering = '{0}' UNION ALL SELECT ProdId FROM CarDetails _
		WHERE Engine ='{1}' UNION ALL SELECT ProdId FROM CarDetails _
		WHERE Fuel ='{2}' UNION ALL SELECT ProdId FROM CarDetails _
		WHERE Brakes ='{3}' UNION ALL SELECT ProdId FROM CarDetails _
		WHERE Lock ='{4}' ) Group By ProdID )ORDER BY Occurence DESC"
        query(2) = String.Format(query(1), cmbSteering.SelectedItem, _
		cmbEngine.SelectedItem, cmbFuel.SelectedItem, _
		cmbBrakes.SelectedItem, cmbLock.SelectedItem)
        commObj = New OleDbCommand(query(2), connObj)
        myAdapter = New OleDbDataAdapter(commObj)
        myAdapter.Fill(myDataSet1, "cDetails")
        connObj.Close() 

所以现在这个查询存储在 var=query(1) 中。

这里,我们所做的是首先在这些列中单独搜索这些术语。例如,转向在转向中,刹车在刹车中,等等..

然后我们将 UNION 所有结果。UNION 将所有结果组合成单个结果集。但是 UNION 不会添加重复的结果,而我们需要重复的结果,因为出现次数最多的结果是最佳匹配项。因此我们使用 UNION ALL

因此在 UNION 之后,我们现在有了组合结果。所以现在,我们将根据出现次数对所有结果进行分组。所以我们有一个超级查询(以及所有 UNION 作为子查询),它使用 COUNT(*) 并使用 GROUP BY 子句对它们进行分组。

但是再次,这将按最少匹配到最佳匹配的顺序对结果进行排序。因此,我们将 COUNT(*) 作为 出现次数,然后使用 ORDER BY 子句以降序对 出现次数 进行排序。

所以这里,在实现此查询之后,我返回了产品 ID(所有行的 Prod ID 唯一)及其出现次数。这只是一个片段,不是一个可用的项目。因此,您需要根据您的代码进行更改。

我希望这篇文章对您有所帮助。:)

关注点

这是我在 CodeProject 上的第一篇文章。我一直在好奇地搜索这个,但没有找到任何相关的文章或代码。所以如果有任何错误、疑问、更正,请告诉我。请原谅我的任何错误,因为我不是专业人士。我是一名学生。

© . All rights reserved.