有什么方法可以更改此SQL,因此这些术语只定义一次?

时间:2013-06-20 22:58:54

标签: mysql sql

我有什么方法可以更改此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

3 个答案:

答案 0 :(得分: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 with Demo

答案 1 :(得分: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
;

See a Live Demo at 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
;

See a Live Demo at 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
;

See a Live Demo at SQL Fiddle

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

答案 2 :(得分: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