令人困惑的 SELECT 语句

发布于 2024-10-19 13:21:57 字数 1114 浏览 3 评论 0原文

首先,我将向您展示与我的问题相关的示例表,然后我将提出问题。

[my_fruits]
fruit_name   |   fruit_id   | fruit_owner   |   fruit_timestamp
----------------------------------------------------------------
Banana       |   3          |  Timmy        |   3/4/11
Banana       |   3          |  Timmy        |   4/1/11
Banana       |   8          |  Timmy        |   5/2/11
Apple        |   4          |  Timmy        |   2/1/11
Apple        |   4          |  Roger        |   3/4/11

现在我想运行一个仅选择fruit_name、fruit_id 和fruit_owner 值的查询。我只想为每个水果获取一行,并且我希望通过最新时间戳来决定它。例如,此表上的完美查询将返回:

[my_fruits]
fruit_name   |   fruit_id   | fruit_owner   |
----------------------------------------------
Banana       |   8          |  Timmy        |
Apple        |   4          |  Roger        | 

我尝试了查询:

select max(my_fruits.fruit_name) keep 
    (dense_rank last order by my_fruits.fruit_timestamp) fruit_name,
       my_fruits.fruit_id, my_fruits.fruit_owner 
from my_fruits 
group by my_fruits.fruit_id, my_fruits.fruit_owner

现在的问题是返回基本上不同的水果名称、水果 ID 和水果所有者。

First I will show you example tables that my issue pertains to, then I will ask the question.

[my_fruits]
fruit_name   |   fruit_id   | fruit_owner   |   fruit_timestamp
----------------------------------------------------------------
Banana       |   3          |  Timmy        |   3/4/11
Banana       |   3          |  Timmy        |   4/1/11
Banana       |   8          |  Timmy        |   5/2/11
Apple        |   4          |  Timmy        |   2/1/11
Apple        |   4          |  Roger        |   3/4/11

Now I want to run a query that only selects fruit_name, fruit_id, and fruit_owner values. I only want to get one row per fruit, and the way I want it to be decided is by the latest timestamp. For example the perfect query on this table would return:

[my_fruits]
fruit_name   |   fruit_id   | fruit_owner   |
----------------------------------------------
Banana       |   8          |  Timmy        |
Apple        |   4          |  Roger        | 

I tried the query:

select max(my_fruits.fruit_name) keep 
    (dense_rank last order by my_fruits.fruit_timestamp) fruit_name,
       my_fruits.fruit_id, my_fruits.fruit_owner 
from my_fruits 
group by my_fruits.fruit_id, my_fruits.fruit_owner

Now the issue with that is returns basically distinct fruit names, fruit ids, and fruit owners.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

沧笙踏歌 2024-10-26 13:21:57

对于 Oracle 9i+,使用:

SELECT x.fruit_name,
       x.fruit_id,
       x.fruit_owner
  FROM (SELECT mf.fruit_name,
               mf.fruit_id,
               mf.fruit_owner,
               ROW_NUMBER() OVER (PARTITION BY mf.fruit_name
                                      ORDER BY mf.fruit_timestamp) AS rank
          FROM MY_FRUIT mf) x
 WHERE x.rank = 1

大多数数据库将支持在派生表/内联视图上使用自联接:

SELECT x.fruit_name,
       x.fruit_id,
       x.fruit_owner
  FROM MY_FRUIT x
  JOIN (SELECT t.fruit_name,
               MAX(t.fruit_timestamp) AS max_ts
          FROM MY_FRUIT t
      GROUP BY t.fruit_name) y ON y.fruit_name = x.fruit_name
                              AND y.max_ts = x.fruit_timestamp

但是,如果有 2 个以上的fruit_name 记录具有相同的时间戳值,这将返回重复项。

For Oracle 9i+, use:

SELECT x.fruit_name,
       x.fruit_id,
       x.fruit_owner
  FROM (SELECT mf.fruit_name,
               mf.fruit_id,
               mf.fruit_owner,
               ROW_NUMBER() OVER (PARTITION BY mf.fruit_name
                                      ORDER BY mf.fruit_timestamp) AS rank
          FROM MY_FRUIT mf) x
 WHERE x.rank = 1

Most databases will support using a self join on a derived table/inline view:

SELECT x.fruit_name,
       x.fruit_id,
       x.fruit_owner
  FROM MY_FRUIT x
  JOIN (SELECT t.fruit_name,
               MAX(t.fruit_timestamp) AS max_ts
          FROM MY_FRUIT t
      GROUP BY t.fruit_name) y ON y.fruit_name = x.fruit_name
                              AND y.max_ts = x.fruit_timestamp

However, this will return duplicates if there are 2+ fruit_name records with the same timestamp value.

东走西顾 2024-10-26 13:21:57

如果您希望每个水果名称占一行,则必须按水果名称分组。

select fruit_name,
       max(my_fruits.fruit_id) keep 
          (dense_rank last order by my_fruits.fruit_timestamp) fruit_id,
       max(my_fruits.fruit_owner) keep 
          (dense_rank last order by my_fruits.fruit_timestamp) fruit_owner
from my_fruits 
group by my_fruits.fruit_name

你想如何处理抢七是一个单独的问题。

If you want one row per fruit name, you have to group by fruit_name.

select fruit_name,
       max(my_fruits.fruit_id) keep 
          (dense_rank last order by my_fruits.fruit_timestamp) fruit_id,
       max(my_fruits.fruit_owner) keep 
          (dense_rank last order by my_fruits.fruit_timestamp) fruit_owner
from my_fruits 
group by my_fruits.fruit_name

How you want to deal with tie-breaks is a separate issue.

南…巷孤猫 2024-10-26 13:21:57

尝试子查询:

select a.fruit_name, a.fruit_id, a.fruit_owner
from my_fruits a
where a.fruit_timestamp =
 (select max(b.fruit_timestamp)
  from my_fruits b
  where b.fruit_id = a.fruit_id)

Try a subquery:

select a.fruit_name, a.fruit_id, a.fruit_owner
from my_fruits a
where a.fruit_timestamp =
 (select max(b.fruit_timestamp)
  from my_fruits b
  where b.fruit_id = a.fruit_id)
紫竹語嫣☆ 2024-10-26 13:21:57

我会通过找出您感兴趣的(fruit_name,fruit_timestamp)列表,然后将该“表”与实际的水果表分组并检索其他值来做到这一点。

SELECT fruit_and_max_t.fruit_name, 
       my_fruits.fruit_id,
       my_fruits.fruit_owner
FROM my_fruits, 
  ( SELECT fruit_name, MAX(fruit_timestamp) AS max_timestamp
    FROM my_fruits
    GROUP BY fruit_name) AS fruit_and_max_t,
WHERE fruit_and_max_t.max_timestamp = my_fruits.fruit_timestamp
  AND fruit_and_max_t.fruit_name    = my_fruits.fruit_name

这假设表中不存在具有相同值(fruit_name,fruit_timestamp)的多个条目,即元组(对)充当唯一标识符。

I would do it by finding out the list of (fruit_name, fruit_timestamp) which are of interest to you, and then grouping that "table" with the actual fruit table and retrieving the other values.

SELECT fruit_and_max_t.fruit_name, 
       my_fruits.fruit_id,
       my_fruits.fruit_owner
FROM my_fruits, 
  ( SELECT fruit_name, MAX(fruit_timestamp) AS max_timestamp
    FROM my_fruits
    GROUP BY fruit_name) AS fruit_and_max_t,
WHERE fruit_and_max_t.max_timestamp = my_fruits.fruit_timestamp
  AND fruit_and_max_t.fruit_name    = my_fruits.fruit_name

This assumes that there are not multiple entries in the table with the same value of (fruit_name, fruit_timestamp), i.e. that tuple (pair) act like a unique identifier.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文