【问题标题】:MySQL - Is it possible to combine two queries without using UNION.?MySQL - 是否可以在不使用 UNION 的情况下组合两个查询?
【发布时间】:2023-03-24 15:00:01
【问题描述】:

我有 2 个具有不同结果集的 SQL 查询。虽然它们都来自同一个表,但第二个查询确实依赖于另一个表。如何在不使用 UNION 的情况下组合这两个查询?

这是我的查询。

SELECT tmp.id, tmp.title , tmp.description, asst.smallUrl, b1.paramVal as duration, b2.paramVal as clips, asst.fileUrl as video
FROM listDb.baseData tmp
INNER JOIN listDb.tag tag ON tag.baseDataId= tmp.id and tag.tag = 'service app' and tag.status = "active"
INNER JOIN listDb.baseParam b0 ON b0.baseDataId= tmp.id
and ((b0.paramName = "role"
and (b0.paramVal = "public"))
or ((select count(*) from listDb.baseParam temp
where temp.baseDataId= tmp.id and paramName = "role" )=0))
or (b0.paramName = "role" and b0.paramVal = "public" and tmp.owner = 27)
LEFT JOIN listDb.baseParam b1 ON b1.baseDataId= tmp.id and b1.paramName="duration" and b1.status = "active"
LEFT JOIN listDb.baseParam b2 ON b2.baseDataId= tmp.id and b2.paramName=" itemCount" and b2.status = "active"
LEFT JOIN listDb.baseParam b3 ON b3.baseDataId= tmp.id and b3.paramName="previewUrl" and b3.status = "active"
LEFT JOIN assetDb.baseData asst ON asst.id = b3.paramVal and asst.status = "active"
WHERE tmp.status = "active" and tmp.application = "template" and tmp.role = "public"

UNION

SELECT tmp.id, tmp.title , tmp.description, asst.smallUrl, b1.paramVal as duration, b2.paramVal as clips, asst.fileUrl as video
FROM listDb.baseData tmp
INNER JOIN listDb.tag tag ON tag.baseDataId= tmp.id and tag.tag = 'service app' and tag.status = "active"
INNER JOIN listDb.baseParam b0 ON b0.baseDataId= tmp.id
and ((b0.paramName = "role"
and (b0.paramVal = "private" or b0.paramVal = "" and b0.paramVal != "public"))
or ((select count(*) from listDb.baseParam temp
where temp.baseDataId= tmp.id and paramName = "role" )=0))
or (b0.paramName = "role" and b0.paramVal = "public" and tmp.owner = 27)
LEFT JOIN listDb.baseParam b1 ON b1.baseDataId= tmp.id and b1.paramName="duration" and b1.status = "active"
LEFT JOIN listDb.baseParam b2 ON b2.baseDataId= tmp.id and b2.paramName="itemCount" and b2.status = "active"
LEFT JOIN listDb.baseParam b3 ON b3.baseDataId= tmp.id and b3.paramName="previewUrl" and b3.status = "active"
LEFT JOIN assetDb.baseData asst ON asst.id = b3.paramVal and asst.status = "active"
INNER JOIN listDb.checkRestricted cr ON cr.baseDataId= tmp.id  and cr.status = "active"  and cr.owner = 27
WHERE tmp.status = "active" and tmp.application = "template" and tmp.role = "private"

【问题讨论】:

  • 除了这个(b0.paramVal = "private" or b0.paramVal = "" and b0.paramVal != "public")之外的查询有什么区别吗?
  • 第二个查询将从另一个表中获取结果.. 在 checkRestricted 表中.. INNER JOIN listDb.checkRestricted cr ON cr.baseDataId= tmp.id and cr.status = "active" and cr.owner = 27

标签: mysql join union


【解决方案1】:

您好,您可以在不使用联合的情况下尝试这些查询

SELECT tmp.id, tmp.title, tmp.description, asst.smallUrl, b1.paramVal AS duration, b2.paramVal AS clips, asst.fileUrl AS video
FROM listDb.baseData tmp INNER JOIN listDb.tag tag ON tag.baseDataId= tmp.id AND tag.tag = 'service app' AND tag.status = "active"
INNER JOIN listDb.baseParam b0 ON b0.baseDataId= tmp.id AND ((b0.paramName = "role" AND ((b0.paramVal = "public") OR (b0.paramVal = "private" OR b0.paramVal = ""))) OR ((
SELECT COUNT(*) FROM listDb.baseParam temp WHERE temp.baseDataId= tmp.id AND paramName = "role")=0)) OR (b0.paramName = "role" AND b0.paramVal = "public" AND tmp.owner = 27)
LEFT JOIN listDb.baseParam b1 ON b1.baseDataId= tmp.id AND b1.paramName="duration" AND b1.status = "active"
LEFT JOIN listDb.baseParam b2 ON b2.baseDataId= tmp.id AND b2.paramName=" itemCount" AND b2.status = "active"
LEFT JOIN listDb.baseParam b3 ON b3.baseDataId= tmp.id AND b3.paramName="previewUrl" AND b3.status = "active"
LEFT JOIN assetDb.baseData asst ON asst.id = b3.paramVal AND asst.status = "active"
WHERE tmp.status = "active" AND tmp.application = "template" AND (tmp.role = "public" OR tmp.role = "private") group by tmp.id

【讨论】:

  • 嗨。我试过你的查询。但这不会返回正确的结果。
【解决方案2】:

所以,查询之间的区别是:

  • 第一个返回b0.paramVal = "public"public "data"
  • 第二个 - b0.paramVal = "private" or b0.paramVal = "" private 或等于 private 并检查限制(checkRestricted table)

逻辑上是:

(b0.paramVal = "public")
OR (b0.paramVal in ("private", "") AND EXISTS(...listDb.checkRestricted)

完整来源:

SELECT
  tmp.id, tmp.title , tmp.description, asst.smallUrl,
  b1.paramVal as duration, b2.paramVal as clips, asst.fileUrl as video
FROM listDb.baseData tmp
INNER JOIN listDb.tag tag
  ON tag.baseDataId= tmp.id and tag.tag = 'service app' and tag.status = "active"
INNER JOIN listDb.baseParam b0
  ON b0.baseDataId= tmp.id
  AND
  (
    b0.paramName = "role"
    OR 
    (
      NOT EXISTS(select 1 from listDb.baseParam temp
        where temp.baseDataId= tmp.id and paramName = "role" )                 ---<<< does this actually mean LEFT JOIN to listDb.baseParam b0 ???
    )
  )
  or (b0.paramName = "role" and b0.paramVal = "public" and tmp.owner = 27)   ---<<< this is very strange in join
LEFT JOIN listDb.baseParam b1
  ON b1.baseDataId= tmp.id and b1.paramName="duration" and b1.status = "active"
LEFT JOIN listDb.baseParam b2
  ON b2.baseDataId= tmp.id and b2.paramName=" itemCount" and b2.status = "active"
LEFT JOIN listDb.baseParam b3
  ON b3.baseDataId= tmp.id and b3.paramName="previewUrl" and b3.status = "active"
LEFT JOIN assetDb.baseData asst
  ON asst.id = b3.paramVal and asst.status = "active"
WHERE tmp.status = "active"
  and tmp.application = "template"
  /* changes to filter (some alterations might be performed if there must be LEFT JOIN to baseparam0 */
  and tmp.role in ("public", "private")
  and (b0.paramVal = "public"
    OR b0.paramVal in ("private", "")
      AND EXISTS(SELECT 1 FROM listDb.checkRestricted cr
        WHERE cr.baseDataId= tmp.id and cr.status = "active"  and cr.owner = 27)
  )

【讨论】:

  • 根据您提供的查询,我无法得到正确的结果。它给了我一个语法错误。
  • 我建议先修复逻辑错误。就像连接中可能产生荒谬输出的奇怪条件一样。
猜你喜欢
  • 2018-08-08
  • 2015-06-23
  • 1970-01-01
  • 2023-04-06
  • 2014-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多