【问题标题】:SQL/PostgreSQL: How to select limited amount of rows of different types based on limits stored in a different table?SQL/PostgreSQL:如何根据存储在不同表中的限制选择有限数量的不同类型的行?
【发布时间】:2016-02-20 00:54:50
【问题描述】:

我有一个表(表 1),其中第一列是键,第二列包含不同类型的元素。在表 1 中,共有三种类型(类型 A、B、C),但实际数据库的类型更多。

Table.1. A minimal example. 
_________________  
|    |           |
|_KEY| attribute |
|____|___________|
|k1  |    A      |
|k2  |    A      |
|k3  |    B      |
|k4  |    C      | 
|k5  |    C      |
|____|___________|

来自表 1;我有兴趣从每种类型中仅检索有限数量的元素。表 2 提供了给定类型的元素数量有限,其中元素类型是表的键 (_element)。

澄清;从表 1 中获取的类型 A 元素的数量有限。在这个最小示例中是 1。同样,对于类型 B,它是 2,对于类型 C,它是 1。

Table 2. Limits of item to obtain for each type in table 1.
____________________
| _Element | Limit |
|----------|-------|
| A        |   1   | 
| B        |   2   |
| C        |   1   | 
|__________|_______|

最后,应该从表 1 中从上到下检索元素。

感谢任何帮助和/或指点/gus。

附言

对于上述最小示例,预期输出为

___________________ 
| Key| Attribute  |
|____|____________|
| k1 | A          |
| k3 | B          |
| K4 | C          |
|____|____________|

因为这个特定的最小示例只存在 1 个 C 属性。请注意,如果存在,例如 C 类型的 5 个元素,则将获得下表(因为 C 元素的数量有限是 2)

___________________ 
| Key| Attribute  |
|____|____________|
| k1 | A          |
| k3 | B          |
| K4 | C          |
|_k5 | C          |
|____|____________|

【问题讨论】:

  • 根据该样本数据,您的预期输出是什么?
  • 是的,您能给我们提供一个输出示例,以便我们更好地提供帮助吗?
  • 谢谢。我已经更新了 O.P.

标签: sql postgresql


【解决方案1】:

你总是可以通过工会来做到这一点。

select top (SELECT Limit FROM Table2 WHERE _Element='A') * from Table1
WHERE attribute = A
UNION ALL
select top (SELECT Limit FROM Table2 WHERE _Element='B') * from Table1
WHERE attribute = B
UNION ALL
select top (SELECT Limit FROM Table2 WHERE _Element='C') * from Table1
WHERE attribute = C

或者使用row_number:

 with cte as (SELECT _Key, 
attribute, 
ROW_NUMBER() OVER (Partition by attribute Order by _Key ASC) as rowno
    From Table1)
    SELECT * FROM cte
    LEFT JOIN Table2 on Table2.Element = Table1.attribute
    WHERE rowno >= Limit

【讨论】:

  • 再想一想,另一条建议使用 count 的评论(似乎已经消失了!)更合适。
  • 谢谢埃德!您的第一种方法将不起作用,因为实际数据库中有更多属性。我正在研究您的第二个解决方案。
【解决方案2】:

我真的很喜欢 PostgreSQL 数组的强大功能。所以

select
  table2._element, 
  unnest((array_agg(table1._key order by table1._key desc)[1:table2.limit])) as _key
from
  table1 join table2 on (table1.attribute = table2._element)
group by
  table2._element, table2.limit

查询的第二个字段中的位置:

array_agg(table1._key order by table1._key desc) - 按指定顺序将值收集到数组中(注意order by table1._key desc 只是示例,您可以跳过它或指定另一个),

(...)[1:table2.limit] - 将数组元素从 1 返回到 table2.limit,

unnest(...) - 将先前的结果展开到行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-25
    • 1970-01-01
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    • 2010-11-15
    相关资源
    最近更新 更多