有没有一种方法可以将这三个SQL查询合并为一个?

时间:2020-10-02 07:36:11

标签: sql h2

我有一些当前正在执行3个SQL(H2)查询以获取结果的代码,我希望它仅执行一个查询。它本身就是功能,所以结果应该相同。

最终结果是根据传入的标题列出电视连续剧推荐内容的两列(标题和等级)。

例如,如果标题为“ Pokemon”,则它返回TVSERIES表中非“ Pokemon”的所有结果,这些结果与GENRES表中的一种或多种类型(例如“ Cartoon”和“喜剧”),并匹配CLASSIFICATIONS表中的分类(例如“ Y-7”),并按照IMDBRATING表中它们的平均IMDb等级返回结果。

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

查询1:

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

1 个答案:

答案 0 :(得分:0)

如今,即使H2拥有WITH clause,也可以用来解决您的问题。

  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)