SQL查询两个表很多列

时间:2012-04-29 13:48:15

标签: c# asp.net sql sql-server-2005

我有两个表,它们具有相同的列但数据不同。他们代表两个不同的日子。这些表是D1Table和D2Table。列是author1,author2,author3,author4,作者5,position1 - position5,title和传记 - 传记5。在查询中,我试图获取与用户在文本框中键入的文本匹配的列(这样他们就可以在两天内进行搜索)。

到目前为止我在第一张桌子上工作正常,但我真的想要搜索第一张和第二张桌子,我只是不知道怎么做,我尝试过使用join和union但是我没有太多幸运的是,我发现错误显然我做错了什么。我正在使用的查询也很长,你可以看到,我相信必须有更好的方法来做到这一点:

txt = "SELECT * from D1Table WHERE Synopsis LIKE '%" + txtBText + 
      "%' OR  Author1 LIKE '%" + txtBText + "%' OR Author2 LIKE '%" + txtBText + 
      "%' OR Author3 LIKE '%" + txtBText + "%' OR Author4 LIKE '%" + txtBText + 
      "%'   OR Author5 LIKE '%" + txtBText + "%' OR Biography1 LIKE '%" + txtBText + 
      "%' OR Biography2 LIKE '%" + txtBText + "%' OR Biography3 LIKE '%" + txtBText + 
      "%' OR Biography4 LIKE '%" + txtBText + "%' OR Biography5 LIKE '%" + txtBText + 
      "%' OR Title LIKE '%" + txtBText + "%'  OR Position1 LIKE '%" + txtBText + 
      "%'OR Position2 LIKE '%" + txtBText + "%' OR Position3 LIKE '%" + txtBText + 
      "%' OR Position4 LIKE '%" + txtBText + "%' OR Position5 LIKE '%" + txtBText + "%' "; 

现在我知道这非常糟糕,因为你可能会说我是垃圾与SQL查询(我刚刚开始学习它们)。我一直在网上寻找一段时间试图学习语法,但这是我所拥有的,所以我认为这可能是我求助的时候。如果有人能给我一些指导,我将不胜感激。

4 个答案:

答案 0 :(得分:2)

我的第一反应就是为什么你需要这样的方法,可能你应该更好地解释你的需求。但无论如何,你最好调查full text search,只需谷歌吧。

以下是一些有用的链接:

http://en.wikipedia.org/wiki/Full_text_search

  

在文本检索中,全文搜索是指用于搜索的技术   单个计算机存储的文档或全文的集合   数据库。全文搜索与基于的搜索不同   元数据或数据库中表示的原始文本的一部分   (如标题,摘要,选定部分或参考书目   参考文献)。

     

在全文搜索中,搜索引擎会检查所有单词   每个存储的文档在尝试匹配搜索条件时(例如,   用户提供的单词)。全文搜索技术成为了   常见于20世纪90年代的在线书目数据库[验证   需要]。许多网站和应用程序(如word   处理软件)提供全文搜索功能。一些网站   AltaVista等搜索引擎采用全文搜索技术   而其他人仅索引其检查的网页的一部分   索引系统。[1]

http://msdn.microsoft.com/en-us/library/ms142571.aspx 以上链接中的一些引用: 将LIKE与全文搜索进行比较

  

与全文搜索相比,LIKE Transact-SQL谓词有效   仅限于字符模式。此外,您不能使用LIKE谓词   查询格式化二进制数据此外,LIKE查询大   非结构化文本数据的数量远远低于等效数据   针对相同数据的全文查询。对数百万人的LIKE查询   文本数据行可能需要几分钟才能返回;而全文   对于相同的数据,查询只需几秒或更短时间,具体取决于   关于返回的行数。

答案 1 :(得分:1)

如果你能够,重新设计表格确实会有所帮助。 根据有多少属性以及将日期划分到不同表中的原因,您可以拥有一个名为DayData的表,其中包含列 日期(可能存储为int或使用SQL 2008 R2的DATE数据类型) 领域 值

如果位置很重要(例如author1在某种程度上与author2不同),那么你也可以有一个索引字段(类型整数)。 这取决于您是否总是拥有每种类型的5个值,或者您是否有0,1或N,以及类型是否可以随时间变化。

无论如何,如果你坚持使用你所拥有的东西,你可以尝试全文搜索,或者如果这是一个太过分的桥梁,试试

"SELECT * from (select * from D1Table UNION D2Table) D1D2
WHERE Synopsis LIKE '%" + txtBText + "%' OR Author1 LIKE '%" + txtBText + "%'
OR Author2 LIKE '%" + txtBText + "%' OR Author3 LIKE '%" + txtBText + "%'
OR Author4 LIKE '%" + txtBText + "%' OR Author5 LIKE '%" + txtBText + "%'
OR Biography1 LIKE '%" + txtBText + "%' OR Biography2 LIKE '%" + txtBText + "%'
OR Biography3 LIKE '%" + txtBText + "%' OR Biography4 LIKE '%" + txtBText + "%' 
OR Biography5 LIKE '%" + txtBText + "%' OR Title LIKE '%" + txtBText + "%' 
OR Position1 LIKE '%" + txtBText + "%'OR Position2 LIKE '%" + txtBText + "%' 
OR Position3 LIKE '%" + txtBText + "%' OR Position4 LIKE '%" + txtBText + "%' 
OR Position5 LIKE '%" + txtBText + "%' "; 

注意名为D1D2的派生表:(从D1Table UNION D2Table中选择*)

但是,您还有另一个问题 - 像您一样构建语句容易受到SQL注入攻击(搜索此站点或Google)。有人可以把

'--delete * from D1Table; 'select * from D1Table where ''1=

并从D1Table中删除数据。主要网站使用类似的技术进行攻击 - 而不是删除数据,操纵查询以生成错误消息或故意的时间延迟,泄漏有关数据库设计和用户名,密码等的信息。

希望有所帮助:)

答案 2 :(得分:0)

虽然我基本同意我在这里看到的其他答案,但我会采用不同的方法来回答:

如果您正在尝试学习SQL,那么您必须训练自己使用更好的格式化。这可能看起来很小,但事实上,如果您使用更易理解的格式,您会发现它易于阅读,理解并且尤其是编辑。

虽然我真的很想念c#中的c / c ++类型块引用,但是几十年的VB编程已经让我适应了没有它们的有些丑陋的要求。比较你的例子:

  

txt =“SELECT * from D1Table WHERE Synopsis LIKE'%”+ txtBText +“%'OR Author1 LIKE'%”+ txtBText +“%'OR Author2 LIKE'%”+ txtBText +“%'OR Author3 LIKE' %“+ txtBText +”%'或者Author4 LIKE'%“+ txtBText +”%'或者Author5 LIKE'%“+ txtBText +”%'或者Biography1 LIKE'%“+ txtBText +”%'或者Biography2 LIKE'%“ + txtBText +“%'或Biography3 LIKE'%”+ txtBText +“%'或Biography4 LIKE'%”+ txtBText +“%'或Biography5 LIKE'%”+ txtBText +“%'OR Title LIKE'%”+ txtBText +“%'或Position1 LIKE'%”+ txtBText +“%'或Position2 LIKE'%”+ txtBText +“%'OR Position3 LIKE'%”+ txtBText +“%'OR Position4 LIKE'%”+ txtBText +“ %'或Position5 LIKE'%“+ txtBText +”%'“;

等同于:

txt = ""
+ "  SELECT  * "
+ "  from    D1Table "
+ "  WHERE   Synopsis    LIKE '%" + txtBText + "%' "
+ "      OR  Author1     LIKE '%" + txtBText + "%' "
+ "      OR  Author2     LIKE '%" + txtBText + "%' "
+ "      OR  Author3     LIKE '%" + txtBText + "%' "
+ "      OR  Author4     LIKE '%" + txtBText + "%' "
+ "      OR  Author5     LIKE '%" + txtBText + "%' "
+ "      OR  Biography1  LIKE '%" + txtBText + "%' "
+ "      OR  Biography2  LIKE '%" + txtBText + "%' "
+ "      OR  Biography3  LIKE '%" + txtBText + "%' "
+ "      OR  Biography4  LIKE '%" + txtBText + "%' "
+ "      OR  Biography5  LIKE '%" + txtBText + "%' "
+ "      OR  Title       LIKE '%" + txtBText + "%' "
+ "      OR  Position1   LIKE '%" + txtBText + "%' "
+ "      OR  Position2   LIKE '%" + txtBText + "%' "
+ "      OR  Position3   LIKE '%" + txtBText + "%' "
+ "      OR  Position4   LIKE '%" + txtBText + "%' "
+ "      OR  Position5   LIKE '%" + txtBText + "%' "
;

显然更容易阅读和更容易理解。什么不是立即显而易见的是它也更容易编辑。考虑您需要通过添加UNION来检查两个表:

txt = ""
// <CUT from here
+ "  SELECT  * "
+ "  from    D1Table "
+ "  WHERE   Synopsis    LIKE '%" + txtBText + "%' "
+ "      OR  Author1     LIKE '%" + txtBText + "%' "
+ "      OR  Author2     LIKE '%" + txtBText + "%' "
+ "      OR  Author3     LIKE '%" + txtBText + "%' "
+ "      OR  Author4     LIKE '%" + txtBText + "%' "
+ "      OR  Author5     LIKE '%" + txtBText + "%' "
+ "      OR  Biography1  LIKE '%" + txtBText + "%' "
+ "      OR  Biography2  LIKE '%" + txtBText + "%' "
+ "      OR  Biography3  LIKE '%" + txtBText + "%' "
+ "      OR  Biography4  LIKE '%" + txtBText + "%' "
+ "      OR  Biography5  LIKE '%" + txtBText + "%' "
+ "      OR  Title       LIKE '%" + txtBText + "%' "
+ "      OR  Position1   LIKE '%" + txtBText + "%' "
+ "      OR  Position2   LIKE '%" + txtBText + "%' "
+ "      OR  Position3   LIKE '%" + txtBText + "%' "
+ "      OR  Position4   LIKE '%" + txtBText + "%' "
+ "      OR  Position5   LIKE '%" + txtBText + "%' "
// CUT to here>
// VV add a UNION
+ " UNION ALL "
// <PASTE here
+ "  SELECT  + "
+ "  from    D2Table "  // <-- change the table name here
+ "  WHERE   Synopsis    LIKE '%" + txtBText + "%' "
+ "      OR  Author1     LIKE '%" + txtBText + "%' "
+ "      OR  Author2     LIKE '%" + txtBText + "%' "
+ "      OR  Author3     LIKE '%" + txtBText + "%' "
+ "      OR  Author4     LIKE '%" + txtBText + "%' "
+ "      OR  Author5     LIKE '%" + txtBText + "%' "
+ "      OR  Biography1  LIKE '%" + txtBText + "%' "
+ "      OR  Biography2  LIKE '%" + txtBText + "%' "
+ "      OR  Biography3  LIKE '%" + txtBText + "%' "
+ "      OR  Biography4  LIKE '%" + txtBText + "%' "
+ "      OR  Biography5  LIKE '%" + txtBText + "%' "
+ "      OR  Title       LIKE '%" + txtBText + "%' "
+ "      OR  Position1   LIKE '%" + txtBText + "%' "
+ "      OR  Position2   LIKE '%" + txtBText + "%' "
+ "      OR  Position3   LIKE '%" + txtBText + "%' "
+ "      OR  Position4   LIKE '%" + txtBText + "%' "
+ "      OR  Position5   LIKE '%" + txtBText + "%' "
// ^^ change these column names if needed
;

这里遗漏的是,对于UNION,SELECT必须返回相同数量的列,并且列的数据类型必须兼容。因此,如果D1Table和D2Table具有不同的列,那么您必须删除“*”并为每个SELECT创建兼容的列列表。

答案 3 :(得分:0)

你可以使用 UNION ALL 并运行两个查询来获得结果......如RBarryYoung所示

SELECT COLUMN1, COLUMN2 FROM TABLE1 WHERE COLUMN1 LIKE '% Variable %' OR COLUMN2 LIKE '% Variable %'
UNION ALL
SELECT COLUMN1, COLUMN2 FROM TABLE2 WHERE COLUMN1 LIKE '% Variable %' OR COLUMN2 LIKE '% Variable %'