Mysql 是否有任何方法可以更改此SQL以便只定义一次术语?

Mysql 是否有任何方法可以更改此SQL以便只定义一次术语?,mysql,sql,Mysql,Sql,是否有任何方法可以更改此SQL以便只定义一次术语? 如果您不想写两次,为什么不创建一个存储术语和分数的表,然后在表上加入: create table terms ( term varchar(50), score int ); insert into terms values ('a railway employee', 3), ('a railway', 2), ('railway employee', 2), ('a', 1), ('railway', 1), ('employe

是否有任何方法可以更改此SQL以便只定义一次术语?


如果您不想写两次,为什么不创建一个存储术语和分数的表,然后在表上加入:

create table terms
(
  term varchar(50),
  score int
);

insert into terms values
('a railway employee', 3),
('a railway', 2),
('railway employee', 2),
('a', 1),
('railway', 1),
('employee', 1);
那么查询将是:

SELECT sum(score) score, title
FROM
(
  SELECT score,title
  FROM terms
  INNER JOIN tableName ON title LIKE concat('%', terms.term, '%')
  UNION ALL
  SELECT score*1.1 score, title
  FROM terms
  INNER JOIN tableName ON summary LIKE concat('%', terms.term, '%')
) AS t
GROUP BY title
ORDER BY score DESC;

请参见

如果您不想写两次,为什么不创建一个存储术语和分数的表,然后在表上加入:

create table terms
(
  term varchar(50),
  score int
);

insert into terms values
('a railway employee', 3),
('a railway', 2),
('railway employee', 2),
('a', 1),
('railway', 1),
('employee', 1);
那么查询将是:

SELECT sum(score) score, title
FROM
(
  SELECT score,title
  FROM terms
  INNER JOIN tableName ON title LIKE concat('%', terms.term, '%')
  UNION ALL
  SELECT score*1.1 score, title
  FROM terms
  INNER JOIN tableName ON summary LIKE concat('%', terms.term, '%')
) AS t
GROUP BY title
ORDER BY score DESC;

也许我不明白这个问题……晚餐……葡萄酒……等等。。。但是您可以使用多个列吗

 select animal, score + score2 as combinedScore
     from
   (
    select 'cat' as animal, 1 as score, 1 * 1.1 as score2
    union
    select 'dog' as animal, 2 as score, 2 * 2.2 as score2
    ) as X

也许我不明白这个问题…晚餐…酒…等等。。。但是您可以使用多个列吗

 select animal, score + score2 as combinedScore
     from
   (
    select 'cat' as animal, 1 as score, 1 * 1.1 as score2
    union
    select 'dog' as animal, 2 as score, 2 * 2.2 as score2
    ) as X

注意:我建议您将这些值放入它们自己的表中。仅仅将它们粘贴在查询文本中可能并不理想。但是,我在下面介绍的查询对于实数表和硬编码的派生表同样有效

这里有一个方法:

SELECT
   sum(score * multiplier) score,
   title
FROM
  (
    SELECT 3 score, 'a railway employee' term UNION ALL
    SELECT 2, 'a railway' UNION ALL
    SELECT 2, 'railway employee' UNION ALL
    SELECT 1, 'a' UNION ALL
    SELECT 1, 'railway' UNION ALL
    SELECT 1, 'employee'
  ) terms
  CROSS JOIN (
    SELECT 'title' which, 1 multiplier
    UNION ALL SELECT 'summary', 1.1
  ) X
  INNER JOIN tableName ON
    CASE
      X.which WHEN 'title' THEN title
      WHEN 'summary' THEN summary
    END
    LIKE concat('%', terms.term, '%')
GROUP BY title
ORDER BY score DESC
;
这是另一种基本上相同但有点混乱的方式:

SELECT
   sum(terms.score * T.multiplier) score,
   title
FROM
  (
    SELECT 3 score, 'a railway employee' term UNION ALL
    SELECT 2, 'a railway' UNION ALL
    SELECT 2, 'railway employee' UNION ALL
    SELECT 1, 'a' UNION ALL
    SELECT 1, 'railway' UNION ALL
    SELECT 1, 'employee'
  ) terms
  INNER JOIN (
    SELECT
      title,
      CASE
         X.which WHEN 'title' THEN title
         WHEN 'summary' THEN summary
      END comparison,
      X.multiplier
    FROM
      tableName
      CROSS JOIN (
        SELECT 'title' which, 1 multiplier
        UNION ALL SELECT 'summary', 1.1
      ) X
   ) T ON T.comparison LIKE concat('%', terms.term, '%')
GROUP BY title
ORDER BY score DESC
;
最后,还有一个方法:

SELECT *
FROM
  (
    SELECT
       sum(
         terms.score * (
           CASE WHEN T.title LIKE concat('%', terms.term, '%') THEN 1 ELSE 0 END
           + CASE WHEN T.summary LIKE concat('%', terms.term, '%') THEN 1.1 ELSE 0 END
         )
       ) score,
       title
    FROM
      tableName T
      CROSS JOIN (
        SELECT 3 score, 'a railway employee' term UNION ALL
        SELECT 2, 'a railway' UNION ALL
        SELECT 2, 'railway employee' UNION ALL
        SELECT 1, 'a' UNION ALL
        SELECT 1, 'railway' UNION ALL
        SELECT 1, 'employee'
      ) terms
    GROUP BY title
    ORDER BY score DESC
  ) Z
WHERE
   Z.score > 0
;

另外,如果MySQL有类似于
交叉应用的东西,它将允许
交叉连接
有一个外部引用,那么其中一些操作会变得更容易(例如,第一个查询可能会完全丢失CASE语句)。

注意:我建议您将值放入它们自己的表中。仅仅将它们粘贴在查询文本中可能并不理想。但是,我在下面介绍的查询对于实数表和硬编码的派生表同样有效

这里有一个方法:

SELECT
   sum(score * multiplier) score,
   title
FROM
  (
    SELECT 3 score, 'a railway employee' term UNION ALL
    SELECT 2, 'a railway' UNION ALL
    SELECT 2, 'railway employee' UNION ALL
    SELECT 1, 'a' UNION ALL
    SELECT 1, 'railway' UNION ALL
    SELECT 1, 'employee'
  ) terms
  CROSS JOIN (
    SELECT 'title' which, 1 multiplier
    UNION ALL SELECT 'summary', 1.1
  ) X
  INNER JOIN tableName ON
    CASE
      X.which WHEN 'title' THEN title
      WHEN 'summary' THEN summary
    END
    LIKE concat('%', terms.term, '%')
GROUP BY title
ORDER BY score DESC
;
这是另一种基本上相同但有点混乱的方式:

SELECT
   sum(terms.score * T.multiplier) score,
   title
FROM
  (
    SELECT 3 score, 'a railway employee' term UNION ALL
    SELECT 2, 'a railway' UNION ALL
    SELECT 2, 'railway employee' UNION ALL
    SELECT 1, 'a' UNION ALL
    SELECT 1, 'railway' UNION ALL
    SELECT 1, 'employee'
  ) terms
  INNER JOIN (
    SELECT
      title,
      CASE
         X.which WHEN 'title' THEN title
         WHEN 'summary' THEN summary
      END comparison,
      X.multiplier
    FROM
      tableName
      CROSS JOIN (
        SELECT 'title' which, 1 multiplier
        UNION ALL SELECT 'summary', 1.1
      ) X
   ) T ON T.comparison LIKE concat('%', terms.term, '%')
GROUP BY title
ORDER BY score DESC
;
最后,还有一个方法:

SELECT *
FROM
  (
    SELECT
       sum(
         terms.score * (
           CASE WHEN T.title LIKE concat('%', terms.term, '%') THEN 1 ELSE 0 END
           + CASE WHEN T.summary LIKE concat('%', terms.term, '%') THEN 1.1 ELSE 0 END
         )
       ) score,
       title
    FROM
      tableName T
      CROSS JOIN (
        SELECT 3 score, 'a railway employee' term UNION ALL
        SELECT 2, 'a railway' UNION ALL
        SELECT 2, 'railway employee' UNION ALL
        SELECT 1, 'a' UNION ALL
        SELECT 1, 'railway' UNION ALL
        SELECT 1, 'employee'
      ) terms
    GROUP BY title
    ORDER BY score DESC
  ) Z
WHERE
   Z.score > 0
;

另外,如果MySQL有类似于
交叉应用
的东西,可以让
交叉连接
有一个外部引用,那么其中的一些操作会变得更容易(例如,第一个查询可能会完全丢失CASE语句)。

什么RDBMS?您使用的是存储过程,还是视图或其他一些单数语句?您可以将它们放入公共表表达式中。根据DBMS的不同,您甚至可以摆脱丑陋的
选择
,并使用(标准)行构造函数
来生成数据。下面是一个示例,说明在DBMS支持ANSI SQL的情况下它会是什么样子:但即使有这样的DBMS,我可能会按照BlueFoot的建议将分数放入自己的表中(而不是临时的)什么RDBMS?您使用的是存储过程还是视图或其他一些单数语句?您可以将它们放入一个公共表表达式中。根据DBMS的不同,您甚至可以摆脱难看的
选择
并使用(标准)行构造函数
values
来生成数据。下面是一个示例,说明了在DBMS支持ANSI SQL的情况下它会是什么样子:但即使有这样一个DBMS,我也可能会按照BlueFoot的建议将分数放入自己的表中(而不是临时表)@Tim True,但我认为这是针对MySQL的,没有CTE可用啊,我应该在插话之前查看小提琴。@Tim True,但我认为这是针对MySQL的,没有CTE可用啊,我应该在插话之前查看小提琴。