我有以下问题:
$imgDimensions_query = "SELECT MAX(imgWidth) maxWidth, MAX(imgHeight) maxHeight FROM (
SELECT imgHeight, imgWidth FROM primary_images WHERE imgId=$imgId
UNION
SELECT imgHeight, imgWidth FROM secondary_images WHERE primaryId=$imgId) as MaxHeight";
它工作得很棒,但我想知道如何为imgId
和maxWidth
值找到maxHeight
列的值以及表名称?
我想要这个的原因是我需要知道maxWidth
和maxHeight
值是否属于数据库中的同一项。
我想知道通过修改当前的SQL查询是否可以做到这一点?
如果同时查询maxWidth
和maxHeight
值,如果同时true
和{maxWidth
,则可以将布尔值设置为输出maxHeight
。 {1}}属于同一条目(至少一次)。
我在想,因为primary_images
中的图像数据与secondary_images
中的数据是唯一的(反之亦然),所以可以在每个查询中设置布尔值,并且如果存在一个true
,则输出true
。那有意义吗?这可能吗?
我设法将第二个查询放在一起,该查询使用第一个查询中的maxWidth
和maxHeight
的值来输出包含两个值的特定集合中的图像数量。所有我真正关心的是,如果是或者不是一个或多个符合上述要求的图像,那么布尔值将比总数更好数。如果你知道如何修改以下内容以显示布尔值而不是结果数,请告诉我!
我已经确信,如果两个表中的最大条目数小于1000,则使用两个查询而不是一个查询不应该导致命中速度。如果您也这么认为,如果将这些查询合并为一个是荒谬的,那么请告诉我。
第二个问题:
$haveDimensions_query = "SELECT sum(rows) AS total_rows FROM (
SELECT count(*) AS rows FROM primary_images WHERE imgId = $imgId and imgWidth = $maxImageWidth and imgHeight = $maxImageHeight
UNION ALL
SELECT count(*) AS rows FROM secondary_images WHERE primaryId = $imgId and imgWidth = $maxImageWidth and imgHeight = $maxImageHeight
) as union_table";
答案 0 :(得分:3)
[原始答案如下 - 这应该更好]
我想我误解了你的问题。以下查询应该为每个图像提供一个结果集,其中包含与所有图像相比具有最大高度或最大宽度的每个图像,并且行中将包含ID和表名以及高度和宽度。
由于最大高度和宽度可能不是来自同一图像,因此结果中不一定只有一行具有单个图像ID和表源。
我希望这至少比你想要的更接近。
SELECT
imgId,
tName,
imgWidth,
imgHeight
FROM (
SELECT imgId, 'Primary' tName, imgHeight, imgWidth
FROM primary_images WHERE imgId=$imgId
UNION
SELECT imgId, 'Secondary' tName, imgHeight, imgWidth
FROM secondary_images WHERE primaryId=$imgId
) as T
WHERE
(T.imgHeight >= (SELECT MAX(imgHeight) FROM primary_images)
AND
T.imgHeight >= (SELECT MAX(imgHeight) FROM secondary_images)
)
OR
(T.imgWidth >= (SELECT MAX(imgWidth) FROM primary_images)
AND
T.imgWidth >= (SELECT MAX(imgWidth) FROM secondary_images)
)
- 以下的原始答案 -
尝试这样的事情:
SELECT
imgId,
tName,
MAX(imgWidth) maxWidth,
MAX(imgHeight) maxHeight FROM (
SELECT imgId, 'Primary' tName, imgHeight, imgWidth
FROM primary_images WHERE imgId=$imgId
UNION
SELECT imgId, 'Secondary' tName, imgHeight, imgWidth
FROM secondary_images WHERE primaryId=$imgId
) as T
GROUP BY imgId, tName;
(MaxHeight不是派生表的好名称,因为它不是最大高度的表。我将其更改为T.)
答案 1 :(得分:1)
这是我到目前为止所得到的。它看起来(并且可能是)非常不理想。尽管如此,我发布它主要是为了介绍一般的想法。希望有人可以开发它以使结果更有效:
SELECT
m.maxWidth,
m.maxHeight,
(u.imgWidth IS NOT NULL) AS OneImageHasBoth
FROM (
SELECT
MAX(imgWidth) AS maxWidth,
MAX(imgHeight) AS maxHeight
FROM (
SELECT imgWidth, imgHeight
FROM primary_images
UNION
SELECT imgWidth, imgHeight
FROM secondary_images
) u
) m
LEFT JOIN (
SELECT imgWidth, imgHeight
FROM primary_images
UNION
SELECT imgWidth, imgHeight
FROM secondary_images
) u ON m.maxWidth = u.imgWidth AND m.maxHeight = u.imgHeight
显然,优化这种方法的一种方法是将重复联合的结果存储到临时表中。我不确定您的特定环境是否允许您发出多语句查询,但如果确实如此,那肯定会有助于加快查询速度。
你想要分别找到每个表的结果然后合并它们的想法实际上并不坏。但我认为结合结果背后的逻辑应该更复杂一些。一个明显的例子是,一个表的结果包含true
而另一个表false
,但后者具有更大的宽度和高度,因此返回true
将是不正确的。或者考虑这个例子:
假设primary_images
的结果是
maxWidth maxHeight OneImageHasBoth
-------- --------- ---------------
1152 864 true
和secondary_images
它的
maxWidth maxHeight OneImageHasBoth
-------- --------- ---------------
1280 800 true
两个表都包含两个属性最大的图像,但很明显,如果查询已应用于联合集,OneImageHasBoth
将为false
。
因此,正如您所看到的,将两个结果组合起来应该比仅依靠其中一个true
的存在更为复杂。
我尝试实施该方法:
SELECT
CASE WHEN p.maxWidth > s.maxWidth THEN p.maxWidth ELSE s.maxWidth END AS maxWidth,
CASE WHEN p.maxHeight > s.maxHeight THEN p.maxHeight ELSE s.maxHeight END AS maxHeight,
(
p.maxWidth >= s.maxWidth AND p.maxHeight >= s.maxHeight AND p.OneImageHasBoth OR
p.maxWidth <= s.maxWidth AND p.maxHeight <= s.maxHeight AND s.OneImageHasBoth
) AS OneImageHasBoth
FROM (
SELECT DISTINCT
m.maxWidth, m.maxHeight,
(i.imgWidth IS NOT NULL) AS OneImageHasBoth
FROM (
SELECT
MAX(imgWidth) AS maxWidth,
MAX(imgHeight) AS maxHeight
FROM primary_images
) m
LEFT JOIN primary_images i ON m.maxWidth = i.imgWidth AND m.maxHeight = i.imgHeight
) p
CROSS JOIN (
SELECT DISTINCT
m.maxWidth, m.maxHeight,
(i.imgWidth IS NOT NULL) AS OneImageHasBoth
FROM (
SELECT
MAX(imgWidth) AS maxWidth,
MAX(imgHeight) AS maxHeight
FROM secondary_images
) m
LEFT JOIN secondary_images i ON m.maxWidth = i.imgWidth AND m.maxHeight = i.imgHeight
) s
答案 2 :(得分:1)
你可以在两个查询中执行此操作,这可能更容易阅读。 第一个查询是获得最大高度和宽度所需要的。
然后,您可以发出第二个查询,如下所示:
SElECT primaryId FROM ( SELECT imgHeight, imgWidth, imgId AS primaryId FROM primary_images UNION SELECT imgHeight, imgWidth, primaryId FROM secondary_images ) as union_table WHERE imgWidth = [maxWidth] and imgHeight = [maxHeight];
[maxWidth]
和[maxHeight]
是您从上一个查询中获得的两个值。如果它们属于同一个图像ID,则查询结果大于零,否则此查询将没有结果。
如果您需要知道哪个ID属于哪个表,您可以创建人工列(例如来源),您的查询将变为:
SElECT primaryId, source FROM ( SELECT imgHeight, imgWidth, imgId AS primaryId, 1 as source FROM primary_images UNION SELECT imgHeight, imgWidth, primaryId, 2 as source FROM secondary_images ) as union_table WHERE imgWidth = [maxWidth] and imgHeight = [maxHeight];
请注意,现在有一个名为source的人工列。因此,如果您的查询结果是
primaryId source 4 1 4 2 5 2
您知道来自imgId
的{{1}} 4以及primary_images
4
来自primaryId
的{{1}} 4,5与上一个查询的最大高度和最大宽度相匹配
最后,如果你只是想知道是否有匹配的图像,根据我们下面的评论和讨论,你可以这样做:
SElECT count(*) AS imgCount FROM ( SELECT imgHeight, imgWidth, imgId AS primaryId FROM primary_images UNION ALL SELECT imgHeight, imgWidth, primaryId FROM secondary_images ) as union_table WHERE primaryId = $imgId and imgWidth = [maxWidth] and imgHeight = [maxHeight];
如果没有匹配的图像,secondary_images
将为零,否则为