获取单行中连接的值的范围(最小值 - 最大值)

Posted

技术标签:

【中文标题】获取单行中连接的值的范围(最小值 - 最大值)【英文标题】:Get range (min - max) of values concatenated in a single row 【发布时间】:2019-03-06 03:37:46 【问题描述】:

给定下表

+-----------------------------+
| id | type | price | item_id |
|-----------------------------|
| 1  | 1    | 20    | 22      |
|-----------------------------|
| 2  | 1    | 22    | 22      |
|-----------------------------|
| 3  | 2    | 19    | 22      |
|-----------------------------|
| 4  | 2    | 11    | 22      |
|-----------------------------|
| 5  | 1    | 08    | 22      |
|-----------------------------|
| 6  | 2    | 25    | 22      |
+-----------------------------+

我正在尝试选择数据以在单行中创建如下视图

+-------------------------------------+
| type1_range | type2_range | item_id |
|-------------------------------------|
| 08 - 22     | 11 - 25     | 22      |
+-------------------------------------+

type1_range 和 type2_range 是每种类型的最低和最高价格。

我可以使用几行获取数据

SELECT type, MAX (price) , MIN (price) 
FROM table 
where item_id=22 GROUP BY type;

+----------------------------+
| type | max | min | item_id |
|----------------------------|
| 1    | 22  | 08  | 22      |
|----------------------------|
| 2    | 25  | 11  | 22      |
+----------------------------+

但我正在尝试像这样连接行:

+-------------------------------------+
| type1_range | type2_range | item_id |
|-------------------------------------|
| 08 - 22     | 11 - 25     | 22      |
+-------------------------------------+

这需要什么 sql?

【问题讨论】:

什么是 RDBMS?请编辑您的数据库标签。如果你有type = 3, 4, 5, ...,会发生什么?您只有 2 个类型值还是无限类型值? 目前只有两种类型和使用postgres 【参考方案1】:

类似这样的:

SELECT
    CONCAT(
      MIN(CASE WHEN type = 1 THEN price END),
      ' - ',
      MAX(CASE WHEN type = 1 THEN price END)
    ) as type1range,
    CONCAT(
      MIN(CASE WHEN type = 2 THEN price END),
      ' - ',
      MAX(CASE WHEN type = 2 THEN price END)
    ) as type2range.
    item_id
FROM table
WHERE item_id = 22
GROUP BY item_id

您已经标记了两个不同的数据库系统(请避免这样做),但我相信它们都支持 CONCAT() 进行字符串连接

如果您想从选择列表中省略 item_id(您已经知道它是第 22 项),您可以删除 GROUP BY。或者,如果您删除 WHERE 并离开组,您将获得每个 item_id 的一行

要进一步了解它的工作原理,请删除 concat 和 min/max - 您会看到仅当类型为 1(在类型 1 范围内)时才会显示价格的情况列),否则为空。是的。对最小值和最大值来说微不足道,只需为每列键入 1 或仅键入 2 数据。如果您想更多地阅读它们,这实际上是一种透视查询的形式

【讨论】:

如果必须在一个范围内给出多个item_id,则此方法无用 你错了;这个查询的功能与你的相同(现在你已经编辑了你的内部连接错误),但总是更有效,因为它只访问和分组表一次 - 你的做 3 次然后加入结果。我会指出,我已经回答了被问到的问题;您似乎试图想象增强尚未提出的要求并为未提出的问题提供答案?【参考方案2】:

直接的方法是将 type1_range 和 type2_range 作为两个子查询,并使用不同的 id 连接,如下所示,

SELECT t.item_id,type1_range,type2_range
FROM (Select distinct item_id from table) t 
LEFT join
(SELECT item_id,type, concat(MIN(price),'-' ,MAX(price) ) as type1_range
FROM table 
where type=1 
GROUP BY item_id,type)type1 on type1.item_id=t.item_id
LEFT join
(SELECT item_id,type, concat(MIN(price),'-' ,MAX(price) ) as type2_range
FROM table 
where type=2 
GROUP BY item_id,type)type2 on type2.item_id=t.item_id

【讨论】:

这是相当复杂且资源密集/浪费的。如果项目没有类型 2,它也不会产生类型 1 的结果,反之亦然 感谢您的洞察力,但为什么如果项目没有类型 2 也不会产生类型 1 的结果,反之亦然? 如果您查看您的编辑历史记录,您会发现您的答案是 INNER JOIN,直到我指出这一点.. 我9分钟前编辑过,你的评论是6分钟前,这就是为什么

以上是关于获取单行中连接的值的范围(最小值 - 最大值)的主要内容,如果未能解决你的问题,请参考以下文章

最大值和最小值的递归范围输出

Matlab中已知函数值的最小值求对应的自变量值...

Pyspark - 从具有最小值和最大值范围的数组中获取值

寻找For循环数组C ++中最大和最小值的值

sql查询时间最小值的列

用于在多张纸上循环的范围内查找最大值和最小值的 VBA 代码