【问题标题】:Is it possible to build following SQL query是否可以构建以下 SQL 查询
【发布时间】:2010-09-11 10:59:44
【问题描述】:

原始查询如下所示(MySQL):

SELECT * 
FROM books 
WHERE title LIKE "%text%" OR description LIKE "%text%" 
ORDER BY date

是否可以重写它(没有联合或过程),所以结果将如下所示:

  • 书名匹配查询的图书列表,按日期排序,后跟:
  • 描述与按日期排序的查询匹配的书籍列表

所以基本上只是将匹配标题比描述赋予更高的优先级。

【问题讨论】:

    标签: sql mysql database


    【解决方案1】:

    联合命令会帮助你。大致如下:

    SELECT *, 1 as order from books where title like '%text%'
    union
    SELECT *, 2 as order from books where description like '%text%'
    ORDER BY order, date
    

    【讨论】:

    • 如果标题和描述都匹配,这将为您提供重复的行。 (它也使用联合。)
    • 它确实使用了您要求避免的联合,但区分联合和联合所有很重要。工会不会产生重复。我怀疑这就是你一开始就避免使用工会的原因。
    【解决方案2】:

    在 sql server 中我会执行以下操作:

    select * from books 
    where title like '%text%' or description like '%text%'
    order by case when title like '%text%' then 1 else 2 end, date
    

    我不确定您是否可以在 mysql 中的 ORDER BY 中包含不在 SELECT 中的列,但这是我要使用的原则。否则,只需将派生列也包含在 SELECT 中。

    【讨论】:

      【解决方案3】:
      select * from books 
      where title like "%text%" or description like "%text%" 
      order by date, case when title like "%text%" then 0 else 1 end
      

      【讨论】:

      • 这将首先按日期排序 - 您应该按部分重新排列订单的顺序。
      【解决方案4】:

      rjk 的建议是正确的方法。但是请记住,这个查询(有或没有联合)不能使用索引,所以它不能很好地扩展。您可能想查看 MySQL 的全文索引,它可以更好地扩展,允许更复杂的查询,甚至有助于结果排名。

      【讨论】:

        【解决方案5】:

        您可以使用大小写进行排序:

        order by case when title like '%text%' then 0 else 1 end
        

        【讨论】:

          【解决方案6】:

          这样的事情怎么样...

          select *  
          from books  
          where title like "%text%"  
          or description like "%text%"  
          order by case when title like "%text%" then 1 else 0 end desc, date
          

          【讨论】:

            【解决方案7】:
            DECLARE @Books TABLE
            (
                [ID] INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
                [Title] NVARCHAR(MAX) NOT NULL,
                [Description] NVARCHAR(MAX) NOT NULL,
                [Date] DATETIME NOT NULL
            )
            
            INSERT INTO @Books
            SELECT 'War and Peace','A Russian Epic','2008-01-01' UNION
            SELECT 'Dogs of War','Mercenary Stories','2006-01-01' UNION
            SELECT 'World At Arms','A Story of World War Two','2007-01-01' UNION
            SELECT 'The B Team','Street Wars','2005-01-01' 
            
            SELECT * FROM
            (
                SELECT *, CASE WHEN [Title] LIKE '%war%' THEN 1 WHEN [Description] LIKE '%war%' THEN 2 END AS Ord
                FROM @Books
                WHERE [Title] LIKE '%war%' OR [Description] LIKE '%war%'
            ) AS Derived
            ORDER BY Ord ASC, [Date] ASC
            

            我相信这可以满足您的需求,但由于派生的 CASE 语句中的额外工作量,它可能没有良好的性能。

            【讨论】:

              猜你喜欢
              • 2014-06-09
              • 1970-01-01
              • 2015-05-23
              • 1970-01-01
              • 2014-01-07
              • 1970-01-01
              • 2023-04-06
              • 1970-01-01
              • 2011-11-01
              相关资源
              最近更新 更多