Sql query to extract constant value in a column between 10 days - mysql

I am trying to write a query which will pull me the employee id's which has stale data for a month in column1.
For ex:
I am maintaining a table where i will store power consumed by an employee per day. Now I want to pull out the emp id's who have maintained power at 30wats constantly for a month.

Try this:-
SELECT emp_id
FROM your_table
GROUP BY emp_id
HAVING ( COUNT ( DISTINCT RANK() OVER ( PARTITION BY emp_id) > 1;
This might be helpful to you.

SELECT empId,TOTAL_SUM FROM
(SELECT empId,SUM(CNT) AS TOTAL_SUM FROM
(SELECT empId,SNAPSHOT_DAY,COUNT(*) AS CNT
FROM emp_details
WHERE power_usage=300
AND SNAPSHOT_DAY>TO_DATE('20150218','yyyymmdd') - 30
AND SNAPSHOT_DAY<=TO_DATE('20150218','yyyymmdd')
GROUP BY empId,SNAPSHOT_DAY
)
GROUP BY empId
)
WHERE total_sum > 29;

Related

A mySQL query for returning customers that make multiple purchases and the specific time of the 5th purchase

"loyal" customers are considered loyal if they have purchased at least 5 times.
I am trying to build an SQL query which returns only "loyal" customers along with the day on
which they become "loyal" customers (the day of their 5th transaction).
user_id
purchase_ts
f594fsae
2021-07-21
........
............
Ideally the desired output would be as follows
loyal_user_id
Loyal_Moment
f594fsae
2021-07-29
..............
............
I tried creating a new table as follows:
SELECT user_id, purchase_ts
FROM Customers
WHERE user_id IN (
SELECT user_id
FROM Customers
GROUP BY user_id
HAVING COUNT (user_id) >=5
)
But I am having trouble, any suggestions?
On MySQL 8 you could use:
with cte as
( select *,
row_number() over (partition by user_id order by purchase_ts asc) row_num
from accounts
)
select user_id,purchase_ts
from cte
where row_num >=5;
Result:
user_id purchase_ts
f594fsae 2021-07-25
f632fsae 2021-07-25
Demo
Since MySQL introduced the support of subquery a long time ago, we have been using its techniques in some MySQL-version-nonspecific scenarios. In this case, we can use a correlated subquery to get exactly the fifth purchase_ts by using the LIMIT [OFFSET] clause. The WHERE clause is used to exclude those purchase_id which doesn't have a fifth purchase_ts.
select distinct user_Id,
(select purchase_ts from purchase where user_id=p.user_id order by purchase_ts limit 4,1) as loyal_time
from purchase p
where (select purchase_ts from purchase where user_id=p.user_id order by purchase_ts limit 4,1) is not null;

Select only newest Entries of DB

I've got a database which has the table updates which contains: product_name, environment, version, date, task.
I need to select only the newest of all and all at one date in time.
Something following will give you all records from max date of each product
select * from table allDates JOIN
( select max(date) maxdate, product from table group by product) maxDates
allDates.Date= maxDates.maxdate and allDates.product= maxDates.product
for all products of latest date
select * from table where date =
( select max(date) maxdate from table)
the newest of all
Anil had a good idea with
SELECT * FROM table ORDER BY date DESC LIMIT 1;
all at one date in time
SELECT * FROM table WHERE DATE(date) = '2017-11-06'
or if your date contains more than just year, month and day
SELECT * FROM table WHERE date LIKE '2017-11-06%'

What is the best way to select rows with maximum value?

I have come across a task, I managed to complete the objective but the solution I got is not optimum, I need more optimum solution. I have used normal Sub Queries May be Correlated Sub Query can solve this better.
This is the table i made
SELECT custid,
count(DISTINCT bid) AS Total
FROM loan
GROUP BY custid;
The output of this is like:-
What I want is the custid having maximum Total.
One way to do it is using Order by Total DESC LIMIT 1 but this will give only 1 result.
What I did is
SELECT custid
FROM (SELECT custid,
count(DISTINCT bid) AS Total
FROM loan
GROUP BY custid) c1
WHERE total = (SELECT max(Total)
FROM (SELECT custid,
count(DISTINCT bid) AS Total
FROM loan
GROUP BY custid) c2)
This gives me correct result that is
What I want to do is reduce the code, because here I am writing the same thing again. I know there must be a simpler way to do it. Maybe a correlated query.
Looking for some good answers. This is basically to clear my concepts only
Sorry, if it is noob question. I am a noob to SQL.
After understand what OP want with #Ravinder 's tip,
I guess build in mysql function GROUP_CONCAT is what you need, sql is:
select custid_count.Total, GROUP_CONCAT(custid_count.custid order by custid_count.custid asc SEPARATOR ',') as custids from
(select custid, count(distinct bid) as Total from loan group by custid order by Total desc) as custid_count
group by custid_count.Total
order by custid_count.Total desc
limit 1;
the result column custids is the max ids concated by ',' ,after the query, you need to split custids by ',' and convert each substring to number type you need,
Here is another way:
select * from loan
where custid =
(
select custid_count.custid from
(select custid, count(distinct bid) as Total from loan group by custid order by Total desc) as custid_count
order by custid_count.Total desc
limit 1
);
First find the custid with max count, then query all rows which match the custid,
I haven't tried this in mysql, but in the sql language I'm using it is fine to use a aggregation function without a group by so something like this
select custid, total, max(total) as maxtotal
from (select custid, count(distinct bid) as total
from loan
group by custid) c1;
would tag on every line both the individual customer total and the table wide max total, and you'd just have to filter on the ones that where the total was equal to the max total. That would give you a final answer of something like this:
select custid
from (select custid, count(distinct bid) as total
from loan
group by custid) c1
where total = max(total);

First 5 entries for a single user

I am using PostgreSQL. I need to get the dates for the first 5 transactions of every user on my DB.
Transaction - trans.id, trans.date, trans.cust_id, trans.value
Customer - cust.id, cust.created_at
I need to get the date of the first 5 transactions for all the customers.
Try this query:
SELECT cust_id, date
FROM (
SELECT cust_id,
date,
row_number() OVER (partition by cust_id
ORDER BY date, id ) rn
FROM Transaction
) as alias
WHERE rn <= 5
ORDER BY 1,2
demo: http://sqlfiddle.com/#!15/cfd2e/4

Aggregating data to get a running total month on month

I have a table which holds the below data
This issue im having is that i need a running total for each month, I've managed to create this is an excel sheet pretty easily but when i try anything in SQL the data result varies.
The image below shows the sum of each paid amount by month, then a total of each one added onto it. I've edited excel to show the formula and the result of the formula. Also have the result i get from SQL 2008 when using (example only)
***UPDATE - The result set im trying to achieve that is in the excel document is for example month 117 + Month 118 gives Month118 TotalToDate, then month 118 + 119 gives Months 119 Total to Date.
Not sure how else to explain this?
( select sum(paid) from #tmp005 t2 where t2.[monthid] <=
t5.[monthid] ) as paid
Really feel that this is less complicated than what I think!
As I understand this you are trying to get a running total month by month, the below CTE should do what you want.
--create table #temp (M_ID Int, Paid Float)
--Insert Into #temp VALUES (116, '50.00'), (117, '50.00'),(117, '5.00'),(117, '20.00'),(117, '10.00'),(117, '75.40'),(118, '125.00'),(118, '200.00'),(118, '5.00')
;WITH y AS
(
SELECT M_ID, paid, rn = ROW_NUMBER() OVER (ORDER BY M_ID)
FROM #temp
), x AS
(
SELECT M_ID, rn, paid, rt = paid
FROM y
WHERE rn = 1
UNION ALL
SELECT y.M_ID, y.rn, y.paid, x.rt + y.paid
FROM x INNER JOIN y
ON y.rn = x.rn + 1
)
SELECT M_ID, MAX(rt) as RunningTotal
FROM x
Group By M_ID
OPTION (MAXRECURSION 10000);
It is based on the first 3 M_ID of your sample data, just change around the #temp to your specific table, I didn't know whether you had another unique identifier in the table which is why I had to use the ROW_NUMBER()but this should order it correctly based on the M_ID field.
I guess that you are storing the month in a separated table and using M_ID to reference it. So, to get the sum of each month do this:
SELECT [M_ID]
,sum([Paid])
FROM #tmp005
GROUP BY [M_ID]
I think I'd use a correlated sub query:-
select r.m_id,
(
select sum(csq.paid)
from #tmp005 csq
where csq.m_id<=r.m_id
)
from (
select distinct m_id
from #tmp005
) r
Hopefully you can figure out how to apply it to your circumstance/schema.