I have a favorite table with 4 columns
employee_id
product_id
frequency
last_consumed_date
Now i'm getting the 6 rows with the highest frequency for the employee_id with a minimal frequency of 6.
Example with employee_id 1
SELECT * FROM `favorites`
WHERE `employee_id` = 1
AND `frequency` >= 6
ORDER BY `frequency` DESC LIMIT 0,6
So far so good!
But now i want to prefer the rows if the last_consumed_date is within a month (30 days), So i must do something with:
DATE_SUB(CURDATE(),INTERVAL 30 DAY) <= `lastchanged`
Here is a table example to make it more clear
Table filled:
1 5 11 2012-10- 3
1 13 8 2012-11- 7
1 18 20 2012- 9-25
1 42 10 2012-11- 3
1 28 15 2012-10-17
1 9 7 2012-10- 8
1 64 9 2012-11- 1
2 24 8 2012- 8-28
2 12 5 2012-10-16
2 5 12 2012-11-11
Today is 2012-11- 8
30 days back is 2012-10- 9
Table returned after SQL:
1 28 15 2012-10-17 <Sorted by 30 days interval and frequency>
1 42 10 2012-11- 3
1 64 9 2012-11- 1
1 13 8 2012-11- 7
1 18 20 2012- 9-25 <Sorted by frequency>
1 5 11 2012-10- 3
Now the question is, How do i order those 2 things in 1 query?
First an order by the date (with 30 days interval)
and than an order by the frequency of seperated results (inside interval and all others)
Ohh i think i found my answer by trial-error ^v^
SELECT * FROM `favorites`
WHERE `employee_id` = 1
AND `frequency` >= 6
ORDER BY (DATE_SUB(CURDATE(),INTERVAL 30 DAY) <= `lastchanged`) DESC,
`frequency` DESC
LIMIT 0,6
For those who tried helping! Thank you
Related
I have a table:
id date val
1 10.08.2022 10
1 12.08.2022 11
1 08.08.2022 15
1 16.08.2022 9
2 02.07.2022 2
2 01.07.2022 4
2 30.07.2022 7
I want to create two new columns last_v and max_v which are equal to last val for each id by date and maximum val per id. So desired output is:
id date val last_v max_v
1 10.08.2022 10 9 15
1 12.08.2022 11 9 15
1 08.08.2022 15 9 15
1 16.08.2022 9 9 15
2 02.07.2022 2 2 7
2 01.07.2022 4 2 7
2 30.06.2022 7 2 7
How could I do that?
You can use window functions!
select t.*,
first_value(val) over(partition by id order by dt desc) last_val,
max(val) over(partition by id) max_val
from mytable t
Demo on DB Fiddle:
id
dt
val
last_val
max_val
1
2022-08-08
15
9
15
1
2022-08-10
10
9
15
1
2022-08-12
11
9
15
1
2022-08-16
9
9
15
2
2022-06-30
7
2
7
2
2022-07-01
4
2
7
2
2022-07-02
2
2
7
I work with this data in table Purchases:
Mat_ID Date Price
11 5.1.2018 10
11 7.1.2018 12
11 9.1.2018 14
12 5.1.2018 10
12 7.1.2018 12
13 9.1.2018 14
13 5.1.2018 10
My desired output query is to have another column with last purchase Price:
Mat_ID Date Price PrevPrice
11 5.1.2018 10 Null
11 7.1.2018 12 10
11 9.1.2018 14 12
12 5.1.2018 10 Null
12 7.1.2018 12 10
13 9.1.2018 14 Null
13 5.1.2018 10 14
Can you recommend something, please?
Thank you!
Try this:
Select
*,
(Select Top 1 Price
From YourTable As T
Where T.Mat_ID = YourTable.Mat_ID And T.[Date] < YourTable.[Date]
Order By T.Mat_ID, T.[Date] Desc) As PrevPrice
From
YourTable
I'm learning HIVE these days and meet some problems...
I have a table called SAMPLE:
USER_ID PRODUCT_ID NUMBER
1 3 20
1 4 30
1 2 25
1 6 50
1 5 40
2 1 10
2 3 15
2 2 40
2 5 30
2 3 35
How can I use HIVE to group table by user_id and in each group order the records by DESC order of NUMBER and in each group I want to keep up to 3 records.
The result I want to have is like:
USER_ID PRODUCT_ID NUMBER(optional column)
1 6 50
1 5 40
1 4 30
2 2 40
2 3 35
2 5 30
or
USER_ID PRODUCT_IDs
1 [6,5,4]
2 [2,3,5]
Could someone help me ?..
Thanks very much!!!!!!!!!!!!!!!!
try this,
select user_id,product_id,number
from(
select user_id,product_id,number, ROW_NUMBER() over (Partition BY user_id) as RNUM
from (
select user_id, number,product_id
from SAMPLE
order by number desc
) t) t2
where RNUM <=3
output
1 6 50
1 5 40
1 4 30
2 2 40
2 3 35
2 5 30
hive version should be 0.11 or greater, may I know if your version is lower
My table votes contains votes that have been made by users at different times:
id item_id position user_id created_at
1 2 0 1 11/21/2013 11:27
26 1 1 1 11/21/2013 11:27
27 3 2 1 11/21/2013 11:27
42 2 2 1 12/7/2013 2:20
41 3 1 1 12/7/2013 2:20
40 1 0 1 12/7/2013 2:20
67 2 2 1 12/13/2013 1:13
68 1 1 1 12/13/2013 1:13
69 3 0 1 12/13/2013 1:13
84 2 0 1 12/28/2013 2:29
83 3 2 1 12/28/2013 2:29
82 1 1 1 12/28/2013 2:29
113 3 0 1 1/17/2014 22:08
114 1 1 1 1/17/2014 22:08
115 2 2 1 1/17/2014 22:08
138 2 0 1 1/20/2014 16:49
139 1 1 1 1/20/2014 16:49
140 3 2 1 1/20/2014 16:49
141 1 1 11 1/20/2014 16:51
142 3 2 11 1/20/2014 16:51
143 2 0 11 1/20/2014 16:51
I need to tally the results on a monthly basis but here's the tricky part: the start/end of the month does not necessarily fall on the first day of the month. So if the votes are due on the 10th day of every month, I need a vote that was cast on the 10th to be in a different group from a vote that was cast on the 11th. Using the data above, I want to get three groups:
Group 1: 6 votes (11/21 and 12/7)
Group 2: 6 votes (12/13, 12/28)
Group 3: 9 votes (1/17, 1/20)
I've tried a lot of approaches but to no avail. This is my query right now:
select created_at, ADDDATE(DATE_FORMAT(created_at, '%Y-%m-01'),interval 10 day) as duedate,count("id") from votes where list_id = 2 group by duedate
I am getting group sizes of 3, 9, and 9, not 6, 6 and 9. Any help you can provide would be much appreciated. Thanks.
Your query is close. You just need to subtract 9 days (10 - 1) from the current day to get the month:
select created_at, date_sub(created_at, interval 9 day) as duedate,
count(id)
from votes
where list_id = 2
group by duedate;
date_format() converts a date to a string. There is no need to convert a date value to a character value for this query.
EDIT:
To group by month:
select date_format(date_sub(created_at, interval 9 day), '%Y-%m') as YYYYMM,
count(id)
from votes
where list_id = 2
group by YYYYMM;
I have a table
date d_id r_id p_id q_sold onhand
2012-10-10 5 1 3025 3 10
2012-10-10 5 1 3022 12 20
2012-10-10 5 1 3023 15 33
2012-10-11 5 1 3025 3 10
2012-10-11 5 1 3022 12 20
2012-10-11 5 1 3023 15 33
2012-10-12 5 1 3025 3 10
2012-10-12 5 1 3022 12 20
2012-10-12 5 1 3023 15 33
2012-10-13 5 1 3025 3 10
2012-10-13 5 1 3022 12 20
2012-10-13 5 1 3023 15 33
2012-10-14 5 1 3025 3 10
2012-10-14 5 1 3022 12 10
2012-10-14 5 1 3023 15 33
2012-10-15 5 1 3025 3 5
2012-10-15 5 1 3022 12 5
2012-10-15 5 1 3023 15 33
I would like to get the result of the q_sold divided by average of the onhand over a 5 day period, while displaying the other data for a specific date like the 2012-10-15.
I create a query
set #stdate = '2012-10-10';
set #endate = '2012-10-15';
SELECT date, d_id,r_id,p_id,q_sold,onhand,qty_sold/AVG(qty_onhand)
FROM stp_vwsales_info_tots
WHERE date BETWEEN #stdate and #endate and d_id=5
GROUP BY d_id,r_id,p_id
But the result being showed is incorrect, it displays the data for the 2012-10-10 instead of 2010-10-15
date d_id r_id p_id q_sold onhand avg
2012-10-10 5 1 3022 12 20 0.7579
2012-10-10 5 1 3023 15 33 0.4545
2012-10-10 5 1 3025 3 10 0.3273
Can anyone help?
Use your #stdate and #endate as DATE(#stdate/#endate) or DATE_FORMAT(#stdate/#endate,'%Y-%m-%d') otherwise you have to convert #stdate/#endate from string to date through MySQL
i think what your looking for is something called a simple moving average.
to calculate this you'll need to use an inline subquery - so performance won't be the best.
assuming you want to calculate the average over the previous 5 day period, try something like this:
SELECT
date, d_id, r_id, p_id, q_sold, onhand,
( SELECT q_sold/AVG(t2.onhand)
FROM stp_vwsales_info_tots AS t2
WHERE p_id=t1.p_id AND DATEDIFF(t1.date, t2.date) BETWEEN 0 AND 4
) AS 'moving_avg'
FROM stp_vwsales_info_tots AS t1
GROUP BY t1.p_id,t1.date
order by t1.date;