【问题标题】:Is there a way to create a WHERE variable in an SQL SELECT request to avoid repetitions?有没有办法在 SQL SELECT 请求中创建 WHERE 变量以避免重复?
【发布时间】:2020-07-27 03:33:57
【问题描述】:

我正在寻找一种将CONCAT_WS('',upper(WT.TitleA),upper(WT.CondB),upper(WT.TitleF),upper(WT.PublisherA),upper(WT.SeriesA)) 放入单个变量的方法,这样就不需要为包含数百个OR LIKE 部分的SQL 搜索输入数百次。

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

【问题讨论】:

  • 用您正在使用的数据库标记您的问题。
  • 附注:CONCAT_WS('', ...) 将字符串直接粘合在一起。 WT.TitleA = 'TIME SPAN' 加上 WT.CondB = 'THERE MUST BE TWO MONTHS LEFT' 变为 'TIME SPANTHERE MUST BE TWO MONTHS LEFT' 匹配 '%PANTHER%'

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


【解决方案1】:

对现有代码的批评:

  • 你不是要CONCAT_WS(' ',...,而不是CONCAT_WS('', ...),这样的话就会分开吗?
  • 不要使用UPPER()(或更低);使用“不区分大小写”的排序规则。
  • 使用LIKE '%...'OR 会导致扫描每一行中的每个字符串列。 (慢!)(而当前的两个答案,虽然满足“concatvar”的请求,但会更慢。)

**为了性能:"

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

然后使用类似的东西

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

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

【讨论】:

    【解决方案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
    

    【讨论】:

      【解决方案3】:

      一种方法是子查询:

      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 或横向连接(如果您的数据库支持)来执行此操作。如果您的数据库支持,您可能还会使用正则表达式。

      【讨论】:

        猜你喜欢
        • 2021-12-15
        • 2020-12-02
        • 2012-06-20
        • 1970-01-01
        • 2013-06-27
        • 2022-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多