MySQL Subquery with datetime comparison from main query values - mysql

I am trying to do what seems like a simple query.. I have a query which works fine until I try to add a subquery to the select clause. I am trying to add a column by querying a second table with the dates I get from the first. I don't know if a join might be better. If you look at my first sample it returns every record in my second table instead of using the date range from the outer select statement.
SELECT `sales`.`date` as 'newdate', `sales`.`material`,
`customer_logs`.`name`, `sales`.`billingqty` ,
(select count(*) from iis_logs where datetime > (select
Date_add(date_format(newdate, "%Y-%m-%d 00:00:00"), interval - 1 day))
and datetime < date_format(newdate, '%Y-%m-%d 00:00:00' and url like
CONCAT('%',material,'%') limit 1) as tr
FROM `sales`
JOIN `customer_logs` ON `customer_logs`.`customer_number` =
`sales`.`soldtopt`
WHERE `date` >= '2017-09-01'
AND `date` <= '2017-09-30'
ORDER BY `date` DESC
LIMIT 10;
If I just type the string as a date in like this it returns within a second:
SELECT `sales`.`date` as 'newdate', `sales`.`material`,
`customer_logs`.`name`, `sales`.`billingqty` ,
(select count(*) from iis_logs where datetime > '2017-09-01 00:00:00'
and datetime < '2017-09-03 00:00:00' and url like
CONCAT('%',material,'%') limit 1) as tr
FROM `sales`
JOIN `customer_logs` ON `customer_logs`.`customer_number` =
`sales`.`soldtopt`
WHERE `date` >= '2017-09-01'
AND `date` <= '2017-09-30'
ORDER BY `date` DESC
LIMIT 10;
It is not taking the value of newdate I am trying to get in select statement, instead it is returning every row in iis_logs table...

This looks like a perfect candidate for a join. FWIW, mysql query optimizer typically does better on joins that subqueries anyway.

Related

MySQL Full Group by

Since my web-host has updated the MySQL server version, my old SQL Query is not working anymore:
select COUNT(ID) AS Anzahl,
DAY(STR_TO_DATE(created_at, '%Y-%m-%d')) AS Datum
from `leads`
where `created_at` >= 2018-02-01
and `created_at` <= 2018-02-15
and `shopID` = 20
group by DAY(created_at)
order by DAY(created_at) asc
That means, I have to create a full group by query. I already have read this article but I don't really get it.
I should name all columns which are unique
Thats what I don't get. If I want to count the ID, I cannot create a group by ID query because in this case my count would always be 1. Could anybody please explain to me how full group by works and how my statement would like with a full group by statement?
Just use the same expression in the select as in the group by:
select COUNT(ID) AS Anzahl, DAY(created_at) AS Datum
from `leads` l
where `created_at` >= '2018-02-01' and
`created_at` <= '2018-02-15' and
`shopID` = 20
group by DAY(created_at)
order by DAY(created_at) asc;
You also need single quotes around the date constants.
Your select and group by columns doesn't match. You should make them same. Try below query:
select COUNT(ID) AS Anzahl,
DAY(STR_TO_DATE(created_at, '%Y-%m-%d')) AS Datum
from `leads`
where `created_at` >= 2018-02-01
and `created_at` <= 2018-02-15
and `shopID` = 20
group by Datum
order by Datum asc

Rewrite sql query to pad empty month rows

I have this query i use to get statistics of blogs in our own tracking system.
I use union select over 2 tables as we daily aggregate data in 1 table and keeps todays data in another table.
I want to have the last 10 months of traffic show.. This query does that, but of there is no traffic in a specific month that row is not in the result.
I have previously used a calendar table in mysql to join against to at avoid that, but im simply not skilled enoght to rewrite this query to join against that calendar table.
The calendart table has 1 field called "datefield" which i date format YYY-MM-DD
This is the current query i use
SELECT FORMAT(SUM(`count`),0) as `count`, DATE(`date`) as `date`
FROM
(
SELECT count(distinct(uniq_id)) as `count`, `timestamp` as `date`
FROM tracking
WHERE `timestamp` > now() - INTERVAL 1 DAY AND target_bid = 92
group by `datestamp`
UNION ALL
select sum(`count`),`datestamp` as `date`
from aggregate_visits
where `datestamp` > now() - interval 10 month
and target_bid = 92
group by `datestamp`
) a
GROUP BY MONTH(date)
Something like this?
select sum(COALESCE(t.`count`,0)),s.date as `date`
from DateTable s
LEFT JOIN (SELECT * FROM aggregate_visits
where `datestamp` > now() - interval 10 month
and target_bid = 92) t
ON(s.date = t.datestamp)
group by s.date

How to query SQL on date AND time

My current table looks like this - Table is called "S"
DJ DATE
---- ------
test yyyy/mm/dd hh:mm:ss
I've worked up to the below SQL query
SELECT *
FROM `S`
WHERE `DATE` = '2017-02-27 17:00:00'
ORDER BY `S`.`DATE` DESC
LIMIT 0 , 1
Rather than having the set date and time though I would like to query based on the current date AND time. I'm using datetime type structure.
All I'm looking to do is query the current datetime to get the current name from the DJ row
Thanks!
You can use now() function to get the current datetime.
SELECT *
FROM `S`
WHERE `DATE` = now()
ORDER BY `S`.`DATE` DESC
LIMIT 0 , 1
If you want to get result for today's date, you can use curdate and date function
SELECT *
FROM `S`
WHERE date(`DATE`) = curdate()
ORDER BY `S`.`DATE` DESC
LIMIT 0 , 1
With mysql, you can use the CURRENT_TIMESTAMP() function.
SELECT *
FROM S
WHERE DATE = CURRENT_TIMESTAMP()
ORDER BY S.DATE DESC
LIMIT 0, 1
I think you want:
select s.*
from s
where date(date) = CURDATE() and
hour(date) = hour(NOW())
order s.date` DESC
limit 0, 1;

Reverse order for GROUP BY in MySQL

I need to select first value for every hour from my db. But I don't know how to reverse order on GROUP BY statement.
How can i rewrite my query (now it selects last value in hour)?
SELECT HOUR(`time`) as hour, mytable.*
FROM mytable
WHERE DATE(`time`) ="2015-09-12" GROUP BY HOUR(`time`) ORDER BY `time` ASC;
This query gave me expected result:
SELECT HOUR(`time`) as hour, sortedTable.* FROM
(SELECT electrolysis.* FROM electrolysis
WHERE DATE(`time`)='2015-09-12' ORDER BY `time`) as sortedTable
GROUP BY HOUR(`time`);
You can just select the MIN HOUR in sub query , try using the query:
SELECT * from mytable WHERE `time` IN (
SELECT MIN(HOUR(`time`)) as `hour`
FROM mytable
WHERE DATE(`time`) ="2015-09-12"
GROUP BY HOUR(`time`) ) ORDER BY `time` ASC;
You can do something like this:-
SELECT sub0.min_time,
mytable.*
FROM mytable
INNER JOIN
(
SELECT MIN(`time`) AS min_time
FROM mytable
GROUP BY HOUR(`time`)
) sub0
ON mytable.`time` = sub0.min_time
WHERE DATE(`time`) ="2015-09-12"
ORDER BY `time` ASC
This is using a sub query to get the smallest time in each hour. This is then joined back against your main table on this min time to get the record that has this time.
Note that there is a potential problem here if there are multiple records that share the same time as the smallest one for an hour. There are ways around this, but that will depend on your data (eg, if you have a unique id field which is always ascending with time then you could select the min id for each hour and join based on that)
You can use below query, which is more optimized just make sure that time field should be indexed.
SELECT HOUR(m.time), m.*
FROM mytable AS m
JOIN
(
SELECT MIN(`time`) AS tm
FROM mytable
WHERE `time` >= '2015-09-12 00:00:00' AND `time` <= '2015-09-12 23:59:59'
GROUP BY HOUR(`time`)
) AS a ON m.time=a.tm
GROUP BY HOUR(m.time)
ORDER BY m.time;

Merging MySQL Queries

I want to merge three queries and I want to get an aggregate result for these three queries, how can i achieve this in MySQL?
My queries
SELECT
order_table_no,
count(bill_no),
sum(finaldiscount)
from order_master
where `ORDER_TABLE_NO` like 'HOME%'
and order_time >= '2015-01-01'
and order_time <= '2015-01-20'
SELECT
distinct(ORDER_TABLE_NO),
sum(order_quantity*order_item_price) AS order_master_FINALDISCOUNT,
count(bill_no)
FROM `order_master` order_master
WHERE date(order_master.`ORDER_TIME`) >= '2015-01-01'
AND date(order_master.`ORDER_TIME`) <= '2015-01-20'
and order_table_no not like 'HOME%'
and order_table_no not like 'TAKE%'
GROUP BY ORDER_TABLE_NO
SELECT
order_table_no,
count(bill_no),
sum(finaldiscount)
from order_master
where `ORDER_TABLE_NO` like 'TAKE%'
and order_time >= '2015-01-01'
and order_time <= '2015-01-20'
It is a bit weird that your first and last query don't have any group by clauses. This doesn't require any joins - just use the MySQL IF Control Flow Function (http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html#function_if):
select
order_table_no,
count(bill_no),
IF(order_table_no like 'TAKE%' or order_table_no like 'HOME%', sum(finaldiscount), sum(order_quantity * order_item_price)) finaldiscount
from
order_master
where
order_time >= '2015-01-01' and
order_time <= '2015-01-20'
group by
order_table_no