简体   繁体   English

修改SQL MAX查询以查找对应字段的值

[英]Amend SQL MAX Query to Find Corresponding Field's Value

I have the following query: 我有以下查询:

$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";

It's working fantastic, but I would like to know how I can find the value of the column imgId , as well as the table name, for both the maxWidth and maxHeight values? 效果很好,但是我想知道如何为maxWidthmaxHeight值找到imgId列的值以及表名?

The reason I want this is I need to know if the maxWidth and maxHeight values belong to the same item in the database. 我想要这个的原因是我需要知道maxWidthmaxHeight值是否属于数据库中的同一项目。

I'm wondering if this is possible by amending the current SQL query? 我想知道是否可以通过修改当前的SQL查询来实现?


What would be perfect is if, along with querying the maxWidth and maxHeight values, a boolean could be set up to output true if both the maxWidth and maxHeight belong to the same entry (at least once). 理想的情况是,如果同时查询maxWidthmaxHeight值,并且可以将布尔值设置为布尔值以输出true如果maxWidthmaxHeight属于同一条目(至少一次))。

I'm thinking, since the image data in primary_images is unique from the data in secondary_images (and vice versa), a boolean could be set up in each of the queries, and as long as one true exists, true is output. 我在想,由于primary_images的图像数据与secondary_images的数据是唯一的(反之亦然),因此可以在每个查询中设置一个布尔值,只要存在一个true ,就输出true Does that make sense? 那有意义吗? Is that possible? 那可能吗?


I have managed to put together a second query which uses the values of maxWidth and maxHeight from the first query to output the number of images in a specific set that hold both values. 我设法将第二个查询放在一起,该查询使用第一个查询中的maxWidthmaxHeight值来输出包含两个值的特定集合中的图像数量。 All I really care about is if there is or if there isn't one or more images that meet the above requirement, so again, a boolean would be better than the total number. 我真正关心的是,如果 ,或者如果没有满足上述要求的一个或多个图像,如此反复,一个布尔值会比总数更好。 If you have an idea of how to amend the following to show a boolean instead of the number of results, let me know! 如果您有想法修改以下内容以显示布尔值而不是结果数,请告诉我!

I have been reassured that with a maximum number of entries in both tables being under 1000, using two queries instead of one shouldn't cause a hit to speed. 我已经放心,两个表中的最大条目数都在1000以下,使用两个查询而不是一个查询不会导致命中速度加快。 If you think so as well, and if combining these queries into one is ridiculous, then let me know that as well. 如果您也这么认为,并且将这些查询组合成一个荒谬的话,也请让我知道。

The second query: 第二个查询:

$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";

[Original answer is below - this should be better] [原始答案在下面-这应该更好]

I think I misunderstood your question. 我想我误会了你的问题。 The following query should give a result set that includes one row for each image that has greatest height or greatest width compared to all images, and it will have the ID and table name in the row along with the height and width. 以下查询应给出一个结果集,该结果集包含与所有图像相比具有最大高度或最大宽度的每个图像的一行,并且该行将在该行中具有ID和表名以及高度和宽度。

Since the maximum height and width may not be from the same image, there can't necessarily be just one row in the result with a single image ID and table source. 由于最大高度和宽度可能并非来自同一图像,因此结果中不一定只有一行具有单个图像ID和表格源。

I hope this is at least closer to what you were looking for. 我希望这至少更接近您的需求。

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)
 )

-- ORIGINAL ANSWER BELOW -- -下面的原始答案-

Try something like this: 尝试这样的事情:

   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 wasn't a good alias name for the derived table, because it isn't a table of maximum heights. I changed it to T.) (对于派生表,MaxHeight并不是很好的别名,因为它不是最大高度的表。我将其更改为T。)

Here's what I've got so far. 这是到目前为止我得到的。 It looks (and probably is) heavily suboptimal. 它看起来(可能是)次优。 Nevertheless, I'm posting it primarily to present the general idea. 不过,我主要将其发布是为了介绍总体思路。 Hopefully, someone might develop it so as to make the result more efficient: 希望有人可以开发它,以使结果更有效:

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

Obviously, one way to optimise this could be to store the result of the repeating union into a temporary table. 显然,一种优化方法是将重复并集的结果存储到临时表中。 I'm not sure if your particular environment allows you to issue multi-statement queries, but if it does, that would definitely help to speed up the query. 我不确定您的特定环境是否允许您发出多语句查询,但是如果可以,那肯定会有助于加快查询速度。

Your idea of finding the results for each table separately and then combining them is actually not bad. 您想要分别找到每个表的结果,然后将它们组合起来的想法实际上还不错。 But I think the logic behind combining the results should be a bit more complex. 但我认为合并结果的逻辑应该更复杂一些。 One obvious example would be, the result for one table contains true and the other false but the latter has bigger width and height, so returning true would be incorrect. 一个明显的例子是,一张表的结果包含true ,而另一张false但后者具有更大的宽度和高度,因此返回true将是不正确的。 Or consider this example: 或考虑以下示例:

Suppose, the result for primary_images is 假设primary_images的结果是

maxWidth  maxHeight  OneImageHasBoth
--------  ---------  ---------------
1152      864        true

and for secondary_images it's 对于secondary_images

maxWidth  maxHeight  OneImageHasBoth
--------  ---------  ---------------
1280      800        true

Both tables have images with both attributes maximal, but it is clear that if the query was applied to the unioned set, OneImageHasBoth would be false . 两个表都具有两个属性都最大的图像,但是很显然,如果将查询应用于联合集,则OneImageHasBoth将为false

So, as you can see, combining the two results should be more intricate than merely relying on the presence of true in one of them. 因此,如您所见,将两个结果相结合应该比仅仅依赖其中之一存在true更为复杂。

Here's my attempt at implementing the method: 这是我实现该方法的尝试:

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

You could do this in two queries, it's probably easier to read that way. 您可以在两个查询中执行此操作,以这种方式读取可能更容易。 First query is what you have to get to get the max height and width. 第一个查询是获得最大高度和最大宽度所必须获得的。

You then can issue the second query which looks like: 然后,您可以发出第二个查询,如下所示:

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];

Where [maxWidth] and [maxHeight] are the two values that you get from previous query. 其中[maxWidth][maxHeight]是您从上一个查询中获得的两个值。 If they belong to the same image ID, you will have query result greater than zero, if not this query will have no result. 如果它们属于相同的图像ID,则查询结果将大于零,否则,查询将没有结果。

If you need to know which id is belong to which table, you could create artificial column (eg source) and your query would become: 如果您需要知道哪个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];

Note that there is now artificial column called source. 请注意,现在有一个名为source的人工列。 So if your result from query is 因此,如果您的查询结果是

primaryId     source
4             1 
4             2
5             2

You know that imgId 4 from primary_images as well as primaryId 4,5 from secondary_images match with the max height and max width of the previous query 你知道imgId 4从primary_images以及primaryId 4,5从secondary_images比赛与之前的查询的最大高度和最大宽度

And finally, if you just want to know whether there is image that is matching or not, per our comments and discussion below, you could do: 最后,如果您只是想知道是否存在匹配的图像,请按照下面的评论和讨论进行:

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];

Where imgCount will be zero if there is no matching image or greater than zero otherwise 如果没有匹配的图像,则imgCount将为零,否则为零

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM