Get minimum values only for duplicates in table - php

I have the following SQL:
set #arbitraryMin = 'two weeks ago';
set #myDesiredMinimumTime = 'thisMorning';
select distinct order, box from db.table
where scantime >= #arbitraryMin
having min(scantime) >= #myDesiredMinimumTime
Essentially, we have a system where it is possible that there are multiple scans for a distinct box/order combo. I only want to get the ones where the minimum scantime is >= #myDesiredMinimumTime. The query above returns two columns with no values in them. I can do this with a sub query, but I was wondering if there was a way to do this without using one.
I am no SQL guru, so I appreciate any help. Table sample (sorry for format):
scantime | Order | Box
2017-06-29 12:34:56 | 123456 | 123
2107-06-29 12:12:12 | 123456 | 124
2017-06-28 14:50:00 | 123456 | 123
Note the two duplicate order/box combos on different days on rows 1 and 3. If I input my query with #arbitraryMin = '2017-06-28 00:00:00' and #myDesiredMinimumTime = '2017-06-29 00:00:00', I only want to get the last two rows, as the top one is a duplicate scan at a different time.
Thank you

That's a invalid SQL. You can't have a HAVING clause without GROUP BY. So the below line is faulty
having min(scantime) >= #myDesiredMinimumTime
You should put that condition in WHERE clause only
where scantime >= #arbitraryMin
and (select min(scantime) from db.table) >= #myDesiredMinimumTime

Thank you to Rahul.
I have found a solution:
select distinct order, box from db.table
where scantime <= #maxTime
group by ordernumber, boxnumber
having min(scantime) >= #myDesiredMinimumTime

Related

Mysql UNION ALL to count multiple columns BUT also insert date column

Hi Guys I have a question. I am still learning and am trying to get some date out. Beneath is the table. It has hundreds of lines, but for example:
FormNR
Datum
XX1
XX2
XX3
0001
2022-09-08
4
23
7
0002
2022-09-10
8
5
0
The table name is 'forms'. Now what I need to do is to count XX1+XX2+XX3 (for a year rapport). Then I have a 'date from and to' selection box on my page. So the question would be:
What instanties have been used between a certain date in total but so that you can see a a total per Instantie (each number is a different instantie).
So for example...Between the 1st of January and the 1st of June a list of all XX numbers ( there are 36 ) with there total behind it
What I have is the following. Is works great and shows all XX's in a nice table but for the entire table, not per date. As soon as i want to add the 'between $date_from AND $date_to' it fails.
<?php
$sql_rg_total="SELECT forms.Datum, x.f1,Count(x.f1)
FROM
(SELECT XX1 As F1 FROM forms
UNION ALL
SELECT XX2 As F1 FROM forms
UNION ALL
SELECT XX3 As F1 FROM forms) x
WHERE x.f1 = '$subcat_id'
GROUP BY x.f1";
$resultvv=mysqli_query($conn, $sql_rg_total);
if (mysqli_num_rows($resultvv) > 0) {
while ($rowvv = mysqli_fetch_assoc($resultvv)) {
$subnr = $rowvv['Count(x.f1)'];
echo $subnr;
}
}
?>
By the way $subcat_id is from another table which connects the number to a name.
I have tried to write it as clear as I could. I know it's a bit thought haha. Thanks anyway for any input. Really stuck.
This query should do it:
SELECT SUM(x.c) AS c
FROM (
SELECT ((XX1 = '$subcat_id') + (XX2 = '$subcat_id') + (XX3 = '$subcat_id')) AS c
FROM forms
WHERE Datum BETWEEN '$date_from' AND '$date_to'
) x
The value of a boolean condition is 1 when it's true, 0 when it's false. So XX1 = '$subcat_id' + XX2 = '$subcat_id' + XX3 = '$subcat_id' adds up the number of columns that match in a row, then SUM(c) totals them in the entire table.
You don't need GROUP BY, since it's the same column that you're filtering in the WHERE condition (and now in the SELECT expression). And this moves the date condition into the subquery.

MYSQL: closest to supplied date grouped by user_id

I need to get multiple rows with a date_added closest to but not past a user supplied date, grouped by user_id.
I've looked at a bunch of max in group type answers but I'm not quite there:
Get nearest records to specific date grouped by type
SQL Query to show nearest date?
Find closest datetime to specified datetime in mysql query
Get closest date from MySQL table
https://dev.mysql.com/doc/refman/5.0/en/example-maximum-column-group-row.html
This is close: https://stackoverflow.com/a/17038667/5319244. Finds the max date though, I need the max specified by user input, not max outright.
Here's a subset of the data with the correct organisation_id, framework_id and level_id already filtered.
+----+---------+-----------------+--------------+----------+---------------------+
| id | user_id | organisation_id | framework_id | level_id | date_added |
+----+---------+-----------------+--------------+----------+---------------------+
| 2 | 1 | 2 | 1 | 1 | 2015-07-31 14:02:49 |
| 9 | 2 | 2 | 1 | 1 | 2015-09-01 11:05:09 |
| 11 | 1 | 2 | 1 | 1 | 2015-09-07 14:13:39 |
+----+---------+-----------------+--------------+----------+---------------------+
If the supplied date is 2015-09-07. I'd expect to see id's: 9 and 11.
If the supplied date is 2015-09-01. I'd expect to see id's: 2 and 9.
If the supplied date is 2015-07-31. I'd expect to see id: 2.
This query is as close as I got:
SELECT t1.id
, t1.user_id
, t1.date_added
FROM
completed_frameworks AS t1
WHERE date_added = (
SELECT
MAX(date_added)
FROM
completed_frameworks
WHERE
user_id = t1.user_id
AND
date_added <= '2015-09-07 23:59:59'
)
AND
(
t1.organisation_id = 2
AND
t1.framework_id = 1
AND
t1.level_id = 1
)
It returns what I expect for the date: 2015-09-07
When the date is 2015-09-01 however it only returns id 9. Not also 2 as I'd expect.
When the date is 2015-07-31 it returns 0 rows..
Let me know if I there's anything else I can provide.
Cheers!
EDIT:
Thanks for the replies thus far. I need to clarify two points:
1) I don't have a limit. I'm expecting those rows due to the user id's. There could be n users returned. I just want a row for each user where the date_added is closest to the user supplied date.
2) The date supplied will not have a time value. It will be from a simple datepicker UI. In my example query I've added the time of 23:59:59 to encompass all of that day.
Try this subquery instead. The organisation_id/framework_id/level_id filter is moved into the subquery and it now returns the right values for the examples you've given.
SELECT t1.id, t1.user_id, t1.date_added
FROM
completed_frameworks AS t1
WHERE date_added = (
SELECT
MAX(date_added)
FROM
completed_frameworks
WHERE
user_id = t1.user_id
AND
date_added <= '2015-09-01 23:59:59'
AND
organisation_id = 2
AND
framework_id = 1
AND
level_id = 1
)
Here is a sample query you could use for an input date of '2015-09-07 14:13:39'. The inner query returns the input date along with the next highest date. This temporary table is then used to filter completed_frameworks to give you only records from the two dates most recent to the input date.
SELECT t1.id, t1.user_id, t1.date_added
FROM completed_frameworks t1
INNER JOIN
(
SELECT cf.date_added
FROM completed_frameworks cf
GROUP BY cf.date_added
HAVING cf.date_added <= '2015-09-07 14:13:39'
ORDER BY cf.date_added DESC
LIMIT 2
) t2
ON t1.date_added = t2.date_added
WHERE t1.organisation_id = 2 AND t1.framework_id = 1 AND t1.level_id = 1
I think this does what you want:
SELECT f.id, f.user_id f.date_added
FROM completed_frameworks f
WHERE date(f.date_added) <= '2025-09-07' -- or whatever your date is
ORDER BY f.date_added DESC
LIMIT 2;
EDIT:
If you want one date per user id that is closest to the specified date, I would suggest:
select f.*
from completed_frameworks f join
(select user_id, max(date_added) as maxda
from completed_frameworks
where date(date_added) <= '2015-09-07'
group by user_id
) u
on f.user_id = u.user_id and f.date_added = maxda

How to filter the total sales record every month using sql query?

I am generating a sales report and I am having a hard time with the query. I am not really good in query. I hope you can help me with this. Ok here it is.
I have a sales table. And the structure is like this
EX:
product_id name date_purchased
1 apple 2014-01-03 12:00:59
2 orange 2014-01-05 10:12:20
3 banana 2014-02-01 09:25:01
4 mango 2014-02-20 18:13:25
5 stawberry 2014-02-28 13:14:30
6 jackfruit 2014-05-26 08:16:31
7 grapes 2014-11-03 09:25:21
8 guava 2014-12-25 10:15:45
Now I want to count the item purchased every month
My output result should be like this
2,3,0,0,1,0,0,0,0,0,1,1
2 represents Jan,
3 represents Feb,
etc...
My query looks like this but I know it is wrong.. :(
SELECT COUNT(product_id) FROM sales_table GROUP BY date_purchased
How can I do that using a query? Or should I make a PHP function for this?
try like this :
SELECT year(date_purchased), month(date_purchased), COUNT(product_id)
FROM sales_table
GROUP BY concat(year(date_purchased), month(date_purchased))
I think you can retrieve the dates and use PHP as it is pretty straight forward.
Once you have a date lets say for example,
$date_str = "2014-01-03 12:00:59"; //let's say you fetch this from DB
$month = date('m',strtotime($date_str)); //this will automatically output 1
You mentioned, 2 represents Jan, 3 represents Feb etc, so you can just add 1 to $month and you have what you need.
Hope it should work
SELECT COUNT(product_id) FROM sales_table GROUP BY DATENAME(month, date_purchased)
The SQL query is enough.
You have to use group by.
But first make a month column for your table.
create function byMonth(#myDate datetime)
returns datetime
as
begin
declare #newDate
set #newDate = year(#myDate) + '/' + month(#myDate) + '/1 00:00:00'
return #newDate
end
go
and use this in your query:
Select Count(*),byMonth(date_puchased) as x
from myTable
where ...
group by x
having ...
this should work for you.
More elaborated solutions
To get Month - wise
SELECT COUNT(id) FROM testrec GROUP BY DATE_FORMAT(pur,'%M');
Get all details
SELECT COUNT(product_id),`name` , date_purchased, DATE_FORMAT(date_purchased,'%M') FROM sales_table GROUP BY DATE_FORMAT(pur,'%M');

MySQL Select from 3 tables and get attendance In and Out Time for all Members in specific date

I have three table Like this:
members_tbl
id | Fullname | Email | MobileNo
attendance_in_tbl
id | member_id | DateTimeIN
attendance_out_tbl
id | member_id | DateTime_OUT
I want to select all members for date: 2014-03-10 by this query:
SELECT
attendance_in.EDatetime,
members_info.mfullname,
attendance_out.ODatetime
FROM
attendance_in
LEFT JOIN members_info ON members_info.id = attendance_in.MemID
LEFT JOIN attendance_out ON attendance_out.MemID = attendance_in.MemID
WHERE date(attendance_in.EDatetime) OR date(attendance_out.ODatetime) = "2014-03-10"
But it give me different results in Attendace_out Results
You have a mistake in your query.
You wrote:
WHERE date(attendance_in.EDatetime) /* wrong! */
OR date(attendance_out.ODatetime) = "2014-03-10"
This is wrong, as the first expression date(attendance_in.EDatetime) always evaluates to true.
You may want
WHERE date(attendance_in.EDatetime) = "2014-03-10"
OR date(attendance_out.ODatetime) = "2014-03-10"
But, this is guaranteed to perform poorly when your attendance_in and attendance_out tables get large, because it will have to scan them; it can't use an index.
You may find that it performs better to write this:
WHERE (attendance_in.EDatetime >='2014-03-10' AND
attendance_in.EDatetime < '2014-03-10' + INTERVAL 1 DAY)
OR (attendance_out.EDatetime >='2014-03-10' AND
attendance_out.EDatetime < '2014-03-10' + INTERVAL 1 DAY)
That will check whether either the checkin our checkout time occurs on the day in question.

cant get maximum date in listing users php MYSQL

I have two tables, and I want to get the last enterd date.
The first table is seeker:
seeker_nic-----username
111-------------ali
222-------------umer
333-------------raza
The second one is requestblood:
id-------seeker_nic-----requireddate
1------- 111 ----------2012/10/9
2 ------- 222-----------2012/5/8
3 ------ 111-----------2012/12/12
4 ------- 111-----------2012/11/12
5---------111-----------2012/09/09
6 ------- 222-----------2012/7/9
7 ------- 333 ----------2012/4/4
Now, I want to list the users with their last inserted date like..
s.no---- username----- requireddate
1------- ali---------- 2012/09/09
2------- umer--------- 2012/7/9
3------- raza--------- 2012/4/4
i am using this query
SELECT seeker.username,bloodrequest.requireddate,
max( bloodrequest.bloodrequest_id ) AS maxdate
FROM seeker
JOIN bloodrequest ON seeker.seeker_nic = bloodrequest.seeker_nic
GROUP BY seeker.username
when i run this query in phpmyadmin.. its lists all user and show the first inserted date of each user.. but i want the last inserted date ... what should i do.. please i need help :(
EDIT for real answer:
Not very clean sql, but it will get you the results you are looking for. I'm sure there's a way do it better with group by, but this works. :)
SELECT s.username,
(
SELECT br1.requireddate
from bloodrequest as br1
where br1.bloodrequest_id =
(
select max(br2.bloodrequest_id)
from bloodrequest as br2
where br2.seeker_nic = s.seeker_nic
)
) as requireddate
FROM seeker as s

Categories