0

有什么办法可以更改此 SQL,以便术语仅定义一次? SQLFiddle

SELECT sum(score) score, title
FROM
(
SELECT
score,
title
FROM
(
  SELECT 3 score, 'a railway employee' term UNION ALL
  SELECT 2 score, 'a railway' term UNION ALL
  SELECT 2 score, 'railway employee' term UNION ALL
  SELECT 1 score, 'a' term UNION ALL
  SELECT 1 score, 'railway' term UNION ALL
  SELECT 1 score, 'employee' term
) terms
INNER JOIN tableName ON title LIKE concat('%', terms.term, '%')
UNION ALL
SELECT
score*1.1 score,
title
FROM
(
  SELECT 3 score, 'a railway employee' term UNION ALL
  SELECT 2 score, 'a railway' term UNION ALL
  SELECT 2 score, 'railway employee' term UNION ALL
  SELECT 1 score, 'a' term UNION ALL
  SELECT 1 score, 'railway' term UNION ALL
  SELECT 1 score, 'employee' term
) terms
INNER JOIN tableName ON summary LIKE concat('%', terms.term, '%')
) AS t
GROUP BY title
ORDER BY score DESC
4

3 回答 3

2

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

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;

请参阅带有演示的 SQL Fiddle

于 2013-06-20T23:03:36.477 回答
1

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

这是一种方法:

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
;

在 SQL Fiddle 上查看现场演示

这是另一种基本相同但稍微改组的方式:

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
;

在 SQL Fiddle 上查看现场演示

最后,还有一种方法:

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
;

在 SQL Fiddle 上查看现场演示

此外,如果 MySQL 有类似的东西CROSS APPLY会让它CROSS JOIN有一个外部引用,那么其中一些会变得更容易(例如,第一个查询可能会完全丢失 CASE 语句)。

于 2013-06-20T23:34:27.033 回答
0

也许我不明白这个问题......晚餐......酒......等等......但是你可以使用多个列吗?

 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
于 2013-06-20T23:20:39.177 回答