3

我有两张桌子 -object_72194_分别是object_72197_

| attr_72195_ |     | attr_72198_ | attr_72199_  |
| 2013-07-31  |     |   a         | 2013-07-31   |
| 2013-07-30  |     |   b         | 2013-07-31   |
| 2013-07-29  |     |   c         | 2013-07-30   |
| 2013-07-28  |     |   d         | 2013-07-29   |

对于第一个表中的每一行,我想attr_72198_从第二个表中获取attr_72199_小于或等于的字段值attr_72195_。因此,在这种情况下,结果将如下所示:

|attr_72195_  | attr_72196_  |
|2013-07-31   | a            |
|2013-07-30   | c            |
|2013-07-29   | d            |
|2013-07-28   | NULL         | 

我想获得每行的价值。现在我的工作查询如下所示:

SELECT f1.attr_72195_, t.attr_72198_ AS attr_72196_ 
FROM object_72194_ f1 
LEFT OUTER JOIN ( 
 SELECT id, attr_72198_, attr_72199_ FROM object_72197_ t 
) AS t ON t.attr_72199_ <= f1.attr_72195_ 
WHERE ( f1.id_obj = 72194 ) AND (t.attr_72199_ = (
 SELECT MAX(attr_72199_) FROM object_72197_ t 
 WHERE attr_72199_ <= f1.attr_72195_
) OR t.attr_72199_ IS NULL

) 按 f1.id_order DESC 排序

它按预期工作。WHERE但由于最后一个块中的子查询,它似乎不是很理想。一位程序员建议我再使用一个加入分组,但我就是不知道怎么做。谢谢!

编辑:删除了子查询中不必要的排序并检查了两个查询(我的查询和连接而不是子查询)并得到了有趣的结果。EXPLAIN 为带有子查询的版本返回五行,为带有连接的版本(id 列)返回四行。在“行”列中,子查询版本有 13 行,连接版本总共有 18 行。因此,必须检查大数据以决定使用哪个版本。

编辑:哦,这个带有连接的查询结果是不正确的,因为它按列对结果进行分组

编辑:这个问题仍然悬而未决。当第二个表中有重复项时,就会出现问题。因此,两个查询都返回与第二个表中一样多的行。但我只需要每行一个值。正如我在示例中一开始就展示了值“a”、“b”、“c”和“d”。

编辑:最后,我做到了。我在第一个表中添加了按唯一字段分组并返回了以前的分组。所以查询现在看起来像这样:

SELECT f1.attr_72195_, f2.attr_72198_ AS attr_72196_ 
FROM object_72194_ f1
INNER JOIN 
(
 SELECT f1.attr_72195_, MAX(f2.attr_72199_) AS attr_72199_
 FROM object_72194_ f1 
 LEFT OUTER JOIN object_72197_ f2 ON f1.attr_72195_ >= f2.attr_72199_
 GROUP BY f1.attr_72195_
) o
ON f1.attr_72195_ = o.attr_72195_
LEFT OUTER JOIN object_72197_ f2 ON f2.attr_72199_ = o.attr_72199_
GROUP BY f1.id, attr_72195_ ORDER BY f1.id_order DESC

简单而优雅。

4

1 回答 1

2

避免相关的子查询(未测试):-

SELECT f1.attr_72195_, MIN(f2.attr_72198_)
FROM object_72194_ f1
INNER JOIN 
(
    SELECT f1.attr_72195_, MAX(f2.attr_72199_) As Max_attr_72199_
    FROM object_72194_ f1 
    LEFT OUTER JOIN object_72197_ f2
    ON f1.attr_72195_ >= f2.attr_72199_
    GROUP BY f1.attr_72195_
) Sub1
ON f1.attr_72195_ = Sub1.attr_72195_
LEFT OUTER JOIN object_72197_ f2
ON f2.attr_72199_ = Sub1.Max_attr_72199_
GROUP BY f1.attr_72195_

在 2 个表之间进行 LEFT JOIN,并从小于或等于第一个表的第二个表中获取最大日期。内连接结果返回到第一个表,左连接到第二个表。不确定当日期重复时您想要 attr_72198_ 的哪个值,所以我刚刚使用 min 函数来获取最小的值。

编辑

试试这个应该可以处理第一张桌子上的重复。

SELECT f1.attr_72195_, f2.attr_72198_
FROM object_72194_ f1
INNER JOIN 
(
    SELECT f1.attr_72195_, MAX(f2.attr_72199_) As Max_attr_72199_
    FROM object_72194_ f1 
    LEFT OUTER JOIN object_72197_ f2
    ON f1.attr_72195_ >= f2.attr_72199_
    GROUP BY f1.attr_72195_
) Sub1
ON f1.attr_72195_ = Sub1.attr_72195_
LEFT OUTER JOIN 
(
    SELECT attr_72199_, MIN(attr_72198_) AS attr_72198_
    FROM object_72197_ 
    GROUP BY attr_72199_
) f2
ON f2.attr_72199_ = Sub1.Max_attr_72199_
于 2013-07-17T12:53:42.007 回答