简体   繁体   中英

Select MIN, MAX Corresponding column based on another column values

I have the following table:

Date        Open        High        Low         Close
1-Oct-19    225.070007  228.220001  224.199997  224.589996
2-Oct-19    223.059998  223.580002  217.929993  218.960007
3-Oct-19    218.429993  220.960007  215.130005  220.820007
4-Oct-19    225.639999  227.490005  223.889999  227.009995
7-Oct-19    226.270004  229.929993  225.839996  227.059998
8-Oct-19    225.820007  228.059998  224.330002  224.399994
9-Oct-19    227.029999  227.789993  225.639999  227.029999
10-Oct-19   227.929993  230.440002  227.300003  230.089996
11-Oct-19   232.949997  237.639999  232.309998  236.210007
14-Oct-19   234.899994  238.130005  234.669998  235.869995
15-Oct-19   236.389999  237.649994  234.880005  235.320007
16-Oct-19   233.369995  235.240005  233.199997  234.369995
17-Oct-19   235.089996  236.149994  233.520004  235.279999
18-Oct-19   234.589996  237.580002  234.289993  236.410004
21-Oct-19   237.520004  240.990005  237.320007  240.509995
22-Oct-19   241.160004  242.199997  239.619995  239.960007
23-Oct-19   242.100006  243.240005  241.220001  243.179993
24-Oct-19   244.509995  244.800003  241.809998  243.580002
25-Oct-19   243.160004  246.729996  242.880005  246.580002
28-Oct-19   247.419998  249.25  246.720001  249.050003
29-Oct-19   248.970001  249.75  242.570007  243.289993
30-Oct-19   244.759995  245.300003  241.210007  243.259995
31-Oct-19   247.240005  249.169998  237.259995  248.759995

For a given date range (say between 03Oct19 to 10Oct19), I want to get the MAXIMUM value of HIGH column and its corresponding date value, and the MINIMUM value of the LOW column and its corresponding date. In the above example, the expected result should be

|  MAX(High)  | High-Date |  MIN(Low)  | Min-Date  |
+-------------+-----------+------------+-----------+
|  230.44002  | 10-Oct-19 | 215.130005 | 03-Oct-19 |

I'm trying the following query:

SELECT max(high)
       , Date
       , min(low)
       , Date 
FROM tbl1 
where date>='2019-10-03' 
and date<='2019-10-10' 
group by date

But, the above code is missing something as it simply returns all the rows.

Any idea what more should be used (join? or nested query?)

Thanks

Try something like this:

select * from 
(SELECT high as "Max(high)"
       , Date_c as "High-Date"
FROM tbl1 
where Date_c >= '2019-10-03' 
and Date_c <= '2019-10-10' 
And high = (select max(high) from tbl1)) a
cross join
(SELECT low as "MIN(Low)"
       , Date_c as "Min-Date"
FROM tbl1 
where Date_c >= '2019-10-03' 
and Date_c<= '2019-10-10' 
And low = (select min(low) from tbl1)) b

Here is a small DEMO for the MySQL 5.7.

Or if for some reason you have two rows that are the same and you want only one result:

select a.high as "Max(high)"
       , a.Date_c "High-Date" 
       , b.low as "MIN(Low)"
       , b.Date_c as "Min-Date"
from 
(SELECT max(high) as "high"
       , max(Date_c) as "Date_c"
FROM tbl1 
where high = (select max(high) 
              from tbl1 
              where Date_c between '2019-10-03' and '2019-10-10')) a
cross join
(SELECT min(low) as "low"
       , max(Date_c) as "Date_c"
FROM tbl1 
where low = (select min(low) 
             from tbl1 
             where Date_c between '2019-10-03' and '2019-10-10')) b

Here is the DEMO for that.

And here is the code according to @SalmanA(Cheers:) advice:

select A.high as "Max(high)"
       , A.Date_c "High-Date" 
       , B.low as "MIN(Low)"
       , B.Date_c as "Min-Date"
from 
(SELECT High, Date_c 
FROM tbl1
where Date_c between '2019-10-03' and '2019-10-10'
ORDER BY High DESC LIMIT 1) A
CROSS JOIN 
(SELECT Low, Date_c 
FROM tbl1 
where Date_c between '2019-10-03' and '2019-10-10'
ORDER BY Low LIMIT 1
) B;

And the DEMO for that.

you can try this:

SELECT
T1.*,T2.*
FROM
(
SELECT  DATE AS  YOUR_MX_DATE,HIGH AS YOUR_HG_VALUE
FROM TBL1 
WHERE   HIGH IN (
SELECT MAX(HIGH) AS MX_VALUE  FROM TBL1 
WHERE   Date >='2019-10-03' 
AND Date <='2019-10-10'  
)
)T1 CROSS JOIN
(
SELECT DATE AS YOUR_MN_DATE,HIGH AS YOUR_MN_VALUE
FROM TBL1 
WHERE LOW IN (
SELECT MIN(LOW) AS MN_VALUE  FROM TBL1 
WHERE   Date >='2019-10-03' 
AND Date <='2019-10-10' 
)
) T2

You first need to find the high and low values for the specified date range, then join with the main table to get corresponding dates. The result will have one row (Highest and Lowest value on same date) or two (Highest and Lowest value on two dates) or possibly more rows (same Highest or Lowest value for multiple dates). Use conditional aggregation to polish the results:

SELECT MIN(CASE WHEN t.High = v.High THEN t.High END) AS High     -- MIN/MAX does not matter here
     , MIN(CASE WHEN t.High = v.High THEN t.Date END) AS HighDate -- MIN for first date, MAX for last date
     , MIN(CASE WHEN t.Low  = v.Low  THEN t.Low  END) AS Low      -- MIN/MAX does not matter here
     , MIN(CASE WHEN t.Low  = v.Low  THEN t.Date END) AS LowDate  -- MIN for first date, MAX for last date
FROM (
    SELECT MAX(High) AS High
         , MIN(Low) AS Low
    FROM t
    WHERE Date BETWEEN '2019-10-03' AND '2019-10-10' 
) AS v
JOIN t ON t.High = v.High OR t.Low = v.Low
WHERE Date BETWEEN '2019-10-03' AND '2019-10-10'

Demo on db<>fiddle

You can use this query to get your desired results. It finds the MAX(high) and MIN(low) values over the period of interest, then JOIN s those values back to the original table to find the corresponding dates. Note we use MIN() on the date values to avoid the situation where a high/low value occurs on more than one day; this gives the earliest date on which it occurs. If you want the latest date on which the high/low value occurs, change that to MAX() .

SELECT hl.high, 
       MIN(t1.date) AS high_date, 
       hl.low, 
       MIN(t2.date) AS low_date
FROM (SELECT MAX(high) AS high, MIN(low) AS low
      FROM tbl1
      WHERE `Date` BETWEEN '2019-10-03' AND '2019-10-10') hl
JOIN tbl1 t1 ON t1.high = hl.high AND t1.date BETWEEN '2019-10-03' AND '2019-10-10'
JOIN tbl1 t2 ON t2.low = hl.low AND t2.date BETWEEN '2019-10-03' AND '2019-10-10'
GROUP BY hl.high, hl.low

Output:

high    low     high_date   low_date
230.44  215.13  2019-10-10  2019-10-03

Demo on dbfiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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