有没有一种方法可以在SQL SELECT请求中创建WHERE变量以避免重复?

时间:2020-04-14 11:59:16

标签: mysql sql join where-clause sql-like

我正在寻找一种将CONCAT_WS('',upper(WT.TitleA),upper(WT.CondB),upper(WT.TitleF),upper(WT.PublisherA),upper(WT.SeriesA))放入单个变量的方法,这样,对于具有数百个OR LIKE部分的SQL搜索,无需键入数百次。 / p>

SELECT
  WT.Sku AS Sku
  , WS.View AS View
  , WT.TitleA AS TitleA
  , WT.Index AS Index
  , WT.CondB AS CondB
  , WT.TitleF AS TitleF
  , WT.PublisherA AS PublisherA
  , WT.SeriesA AS SeriesA

FROM
  wt_table_one AS WT
  INNER JOIN public.ws_table_one AS WS ON WT.Index = WS.Index
WHERE
  WS.View = 17
  AND (
  CONCAT_WS('',upper(WT.TitleA),upper(WT.CondB),upper(WT.TitleF),upper(WT.PublisherA),upper(WT.SeriesA))  LIKE '%PANTHER%'
  OR CONCAT_WS('',upper(WT.TitleA),upper(WT.CondB),upper(WT.TitleF),upper(WT.PublisherA),upper(WT.SeriesA))  LIKE '%WISHING%'
  OR (CONCAT_WS('',upper(WT.TitleA),upper(WT.CondB),upper(WT.TitleF),upper(WT.PublisherA),upper(WT.SeriesA))  LIKE '%MIGHTY%' AND CONCAT_WS('',upper(WT.TitleA),upper(WT.CondB),upper(WT.TitleF),upper(WT.PublisherA),upper(WT.SeriesA))  LIKE '%THOR%')
  OR (CONCAT_WS('',upper(WT.TitleA),upper(WT.CondB),upper(WT.TitleF),upper(WT.PublisherA),upper(WT.SeriesA))  LIKE '%ANIMAL%' AND CONCAT_WS('',upper(WT.TitleA),upper(WT.CondB),upper(WT.TitleF),upper(WT.PublisherA),upper(WT.SeriesA))  LIKE '%CROSSING%')
  OR (CONCAT_WS('',upper(WT.TitleA),upper(WT.CondB),upper(WT.TitleF),upper(WT.PublisherA),upper(WT.SeriesA))  LIKE '%BRIAN%' AND CONCAT_WS('',upper(WT.TitleA),upper(WT.CondB),upper(WT.TitleF),upper(WT.PublisherA),upper(WT.SeriesA))  LIKE '%BLESSED%')
  OR (CONCAT_WS('',upper(WT.TitleA),upper(WT.CondB),upper(WT.TitleF),upper(WT.PublisherA),upper(WT.SeriesA))  LIKE '%ONE%' AND CONCAT_WS('',upper(WT.TitleA),upper(WT.CondB),upper(WT.TitleF),upper(WT.PublisherA),upper(WT.SeriesA))  LIKE '%OF%' AND CONCAT_WS('',upper(WT.TitleA),upper(WT.CondB),upper(WT.TitleF),upper(WT.PublisherA),upper(WT.SeriesA))  LIKE '%A%' AND CONCAT_WS('',upper(WT.TitleA),upper(WT.CondB),upper(WT.TitleF),upper(WT.PublisherA),upper(WT.SeriesA))  LIKE '%KIND%')
  )
LIMIT 10000

(还有大约一百种LIKE条件,但我在这里已将其削减了)

我是SQL的新手,请多多包涵,但是我尝试了以下方法。

SELECT
  @concvar :=CONCAT_WS('',upper(WT.TitleA),upper(WT.CondB),upper(WT.TitleF),upper(WT.PublisherA),upper(WT.SeriesA))
  ,WT.Sku AS Sku
...
SET @concvar =CONCAT_WS('',upper(WT.TitleA),upper(WT.CondB),upper(WT.TitleF),upper(WT.PublisherA),upper(WT.SeriesA))
SELECT
  WT.Sku AS Sku
...

来自https://www.oreilly.com/library/view/mysql-cookbook/0596001452/ch01s15.html

一切照旧,一切照旧,但是我只希望有一个地方来更新它而不是数百个地方。

-编辑- 我的目标将是这样。

CONCATVAR = CONCAT_WS('',upper(WT.TitleA),upper(WT.CondB),upper(WT.TitleF),upper(WT.PublisherA),upper(WT.SeriesA))

SELECT
  WT.Sku AS Sku
  , WS.View AS View
  , WT.TitleA AS TitleA
  , WT.Index AS Index
  , WT.CondB AS CondB
  , WT.TitleF AS TitleF
  , WT.PublisherA AS PublisherA
  , WT.SeriesA AS SeriesA

FROM
  wt_table_one AS WT
  INNER JOIN public.ws_table_one AS WS ON WT.Index = WS.Index
WHERE
  WS.View = 17
  AND (
  CONCATVAR  LIKE '%PANTHER%'
  OR CONCATVAR  LIKE '%WISHING%'
  OR (CONCATVAR  LIKE '%MIGHTY%' AND CONCATVAR  LIKE '%THOR%')
  OR (CONCATVAR  LIKE '%ANIMAL%' AND CONCATVAR  LIKE '%CROSSING%')
  OR (CONCATVAR  LIKE '%BRIAN%' AND CONCATVAR  LIKE '%BLESSED%')
  OR (CONCATVAR  LIKE '%ONE%' AND CONCATVAR  LIKE '%OF%' AND CONCATVAR  LIKE '%A%' AND CONCATVAR  LIKE '%KIND%')
  )
LIMIT 10000

3 个答案:

答案 0 :(得分:2)

您可以使用子查询:

SELECT 
    WT.Sku AS Sku
    , WS.View AS View
    , WT.TitleA AS TitleA
    , WT.Index AS Index
    , WT.CondB AS CondB
    , WT.TitleF AS TitleF
    , WT.PublisherA AS PublisherA
    , WT.SeriesA AS SeriesA
FROM (
    SELECT
        WT.*,
        CONCAT_WS('',upper(WT.TitleA),upper(WT.CondB),upper(WT.TitleF),upper(WT.PublisherA),upper(WT.SeriesA)) 
    FROM wt_table_one AS WT
    INNER JOIN public.ws_table_one AS WS ON WT.Index = WS.Index
    WHERE WS.View = 17
) t
WHERE  
    mycol LIKE '%PANTHER%'
    OR myval  LIKE '%WISHING%'
    OR (myval LIKE '%MIGHTY%' AND myval LIKE '%THOR%')
    OR (myval LIKE '%ANIMAL%' AND myval LIKE '%CROSSING%')
    OR (myval LIKE '%BRIAN%'  AND myval LIKE '%BLESSED%')
    OR (myval LIKE '%ONE%'    AND myval LIKE '%OF%' AND myval LIKE '%A%' AND myval  LIKE '%KIND%')
LIMIT 10000

答案 1 :(得分:1)

一种方法是子查询:

SELECT wt.*
FROM (SELECT wt.*,
             CONCAT_WS('', upper(WT.TitleA), upper(WT.CondB), upper(WT.TitleF), upper(WT.PublisherA), upper(WT.SeriesA)) as concat_str
      FROM wt_table_one wt JOIN
           public.ws_table_one ws
           ON WT.Index = WS.Index
      WHERE WS.View = 17
     ) wt
WHERE wt.concat_str LIKE '%PANTHER%' OR
      wt.concat_str LIKE '%WISHING%' OR
      (wt.concat_str LIKE '%MIGHTY%' AND wt.concat_str LIKE '%THOR%') OR
      (wt.concat_str LIKE '%ANIMAL%' AND wt.concat_str LIKE '%CROSSING%') OR
      (wt.concat_str LIKE '%BRIAN%' AND wt.concat_str LIKE '%BLESSED%') OR
      (wt.concat_str LIKE '%ONE%' AND wt.concat_str LIKE '%OF%' AND wt.concat_str LIKE '%A%' AND wt.concat_str LIKE '%KIND%')
      )
LIMIT 10000

您还可以使用CTE或横向联接(如果数据库支持)来执行此操作。如果数据库支持的话,您可能还会使用正则表达式。

答案 2 :(得分:0)

对现有代码的评论:

  • 您不是要CONCAT_WS(' ',...,而不是CONCAT_WS('', ...),以便单词分开吗?
  • 请勿使用UPPER()(或更低版本);使用不区分大小写的排序规则。
  • 使用LIKE '%...'OR导致扫描每一行中的每个字符串列。 (慢!)(并且当前的两个Answers在满足“ concatvar”的请求的同时,会变得更慢。)

**对于性能:“

构建表时,添加一个TEXT列,将所有单词集中在一起。然后在该列上建立一个FULLTEXT索引。

然后使用类似的东西

MATCH(text_col) AGAINST (
     ''panther wishing "mighty thor" "animal crossing"'
     IN BOOLEAN MODE)

阅读FULLTEXT的功能和限制。例如,one of可能无法实际包含在测试中。 (这是因为最小字长。)