首页 > 解决方案 > 有没有办法将这三个 SQL 查询合并为一个?

问题描述

我有当前正在执行 3 个 SQL (H2) 查询以获取结果的代码,我希望它只执行一个查询。它是功能性的,所以结果应该是一样的。

最终结果是基于传入标题的电视连续剧推荐的两列(标题和评级)列表。

例如,如果标题为“Pokemon”,则返回表中所有非“Pokemon”的结果TVSERIES,匹配表中的一个或多个类型GENRES(例如“卡通”和“喜剧”),并匹配CLASSIFICATIONS表中的分类(例如“Y-7”),并按照表中的平均 IMDb 评级顺序返回结果IMDBRATING

前两个仅用于填充第三个查询的 WHERE 子句 - 第三个是真正完成大部分工作的那个。

查询一:

SELECT GENRE FROM GENRES
LEFT JOIN TVSERIES ON GENRES.TVSERIESID = TVSERIES.ID
WHERE TVSERIES.TITLE = 'A Title'

然后我遍历任何结果以创建一个类似的字符串GENRES.GENRE = 'Comedy' OR GENRES.GENRE = 'Drama'(可以有任意数量的行)并将其存储为变量genresCondition

查询 2:

SELECT CLASSIFICATION FROM CLASSIFICATIONS
LEFT JOIN TVSERIES ON CLASSIFICATIONS.TVSERIESID = TVSERIES.ID
WHERE TVSERIES.TITLE = `A Title`
LIMIT 1

然后我将该结果存储为类似字符串CLASSIFICATIONS.CLASSIFICATION = 'PG-13'并将其存储为变量classificationCondition

查询 3:

SELECT DISTINCT TVSERIES.TITLE, IMDBRATINGS.IMDBRATING
FROM TVSERIES
LEFT JOIN GENRES ON TVSERIES.ID = GENRES.TVSERIESID
LEFT JOIN IMDBRATINGS ON TVSERIES.ID = IMDBRATINGS.TVSERIESID
LEFT JOIN CLASSIFICATIONS ON TVSERIES.ID = CLASSIFICATIONS.TVSERIESID
WHERE
(genresCondition) AND
classificationCondition AND
TVSERIES.TITLE != 'A Title'
ORDER BY IMDBRATINGS.IMDBRATING DESC

标签: sqlh2

解决方案


现在连 H2 都有一个WITH子句,可以用来解决你的问题。

  1. 使用第一个查询,将其放入WITH子句中。
  2. 获取第二个第二个查询并使用第一个查询的结果。
  3. 将所有内容放在第二with个子句中。
  4. 并应用第三个查询。

我昨天写的类似的东西:

with "Smartcards" as
(
  with "Modules" as
  (
    select e."Serial Number" as serno,
           m."Smartcard 1" as g1,
           m."Smartcard 2" as g2,
           m."Smartcard 3" as g3
    from   "Type 1" e,
           "Module" m
    where  e."Serial Number" = "Device Certificate Validity End"."Serial Number" and
           e."Module" = m."ID"
    union
    select r."Serial Number" as serno,
           m."Smartcard 1" as g1,
           m."Smartcard 2" as g2,
           m."Smartcard 3" as g3
    from   "Type 2" r,
           "Module" m
    where  r."Serial Number" = "Device Certificate Validity End"."Serial Number" and
           (r."Left Module" = m."ID" or r."Right Module" = m."ID")
  )
  select m.serno,
         g."RSA Certificate" as rsa,
         g."ECC Certificate" as ecc
  from   "Modules" m,
         "Smartcard" g
  where  g."ID" in (m.g1, m.g2, m.g3)
)
select min(c."Validity Not After") as "Validity Not After"
from   "Smartcards" g,
       "Certificate" c
where  c."ID" in (g.rsa, g.ecc)

推荐阅读