I have following mysql query:
SELECT m.emp_id AS `Empid`
, d.dt AS `AbsentDate`,
(CASE WHEN p.punch_status IS NULL
THEN 'A'
ELSE p.punch_status
END
) s
FROM ( SELECT DATE(t.added_date) AS dt
FROM pmc_attendance t
WHERE date(t.added_date) >= '2018-08-01'
AND date(t.added_date) < DATE_ADD( '2018-08-31' ,INTERVAL 1 DAY)
GROUP BY DATE(t.added_date)
ORDER BY DATE(t.added_date)
) d
CROSS
JOIN tbl_admin_users m
LEFT
JOIN pmc_attendance p
ON date(p.added_date) >= d.dt
AND date(p.added_date) < d.dt + INTERVAL 1 DAY
AND p.emp_id = m.emp_id
WHERE p.emp_id IS NULL and m.emp_id='000838' group by d.dt
ORDER
BY m.emp_id
, d.dt
this would fetch all the absent records of the employee but i want to show present dates of employees also.
enter image description here
my sql record shows:
Empid AbsentDate
000838 2018-08-05
000838 2018-08-05
000838 2018-08-11
000838 2018-08-12
000838 2018-08-15
000838 2018-08-19
I have use two tables
1. tbl_admin_users- employee data stored
2. pmc_attendance- present records of employees
As mention in my query, I had removed p.emp_id IS NULL condition.
Due to this condition all your record which have p.punch_status is not null get filter out.
So you can try below query
SELECT m.emp_id AS `Empid`
, d.dt AS `AbsentDate`,
(CASE WHEN p.punch_status IS NULL
THEN 'A'
ELSE p.punch_status
END
) s
FROM ( SELECT DATE(t.added_date) AS dt
FROM pmc_attendance t
WHERE date(t.added_date) >= '2018-08-01'
AND date(t.added_date) < DATE_ADD( '2018-08-31' ,INTERVAL 1 DAY)
GROUP BY DATE(t.added_date)
ORDER BY DATE(t.added_date)
) d
CROSS
JOIN tbl_admin_users m
LEFT
JOIN pmc_attendance p
ON date(p.added_date) >= d.dt
AND date(p.added_date) < d.dt + INTERVAL 1 DAY
AND p.emp_id = m.emp_id
WHERE m.emp_id='000838' group by d.dt
ORDER
BY m.emp_id
, d.dt
Related
I have been struggling to make a single sql query that would give the result of all 3 queries in one. I suppose I would need to use full joins.
These 3 queries are all grouped by hour_key and store_id and ordered by hour_key.
The 3 queries are the following :
select SUM(qty_invoiced) as diag, DATE_FORMAT(a.created_at, '%Y-%m-%d-%h') as hour_key, b.store_id
from sales_flat_order_item a inner join
sales_flat_order b
on (a.order_id = b.entity_id)
where a.created_at BETWEEN (NOW() - INTERVAL 7 DAY) AND NOW() AND
a.parent_item_id IS NULL AND
a.sku LIKE 'D-%' AND b.status in ('processing', 'complete', 'printed', 'ready_to_print', 'ready_to_ship')
GROUP BY DATE_FORMAT(a.created_at, '%Y-%m-%d-%h'), b.store_id
ORDER BY hour_key DESC
select SUM(grand_total) as grand_total, store_id , DATE_FORMAT(created_at, '%Y-%m-%d-%h') as hour_key, SUM(shipping_amount) as shipping
from sales_flat_order
where created_at BETWEEN (NOW() - INTERVAL 7 DAY) AND NOW() AND status in ('processing', 'complete', 'printed', 'ready_to_print', 'ready_to_ship')
GROUP BY DATE_FORMAT(created_at, '%Y-%m-%d-%h'), store_id
ORDER BY hour_key DESC
SELECT COUNT(a.entity_id) as totalPaniers, a.store_id, DATE_FORMAT(a.created_at, '%Y-%m-%d-%h') as hour_key
FROM sales_flat_quote a
WHERE a.created_at BETWEEN (NOW() - INTERVAL 7 DAY) AND NOW()
GROUP BY DATE_FORMAT(a.created_at, '%Y-%m-%d-%h'), a.store_id
ORDER BY hour_key DESC
We don't know what your table structure is, so my best guess is
SELECT
DATE_FORMAT(a.created_at, '%Y-%m-%d-%h') as hour_key,
COUNT(entity_id) as totalPaniers,
store_id,
SUM(grand_total) as grand_total,
SUM(shipping_amount) as shipping,
SUM(qty_invoiced) as diag
FROM
sales_flat_quote a
[LEFT] JOIN sales_flat_order b ON a.store_id=b.store_id
INNER JOIN sales_flat_order_item c ON c.order_id=b.entity_id
WHERE
a.created_at BETWEEN (NOW() - INTERVAL 7 DAY) AND NOW()
AND b.created_at BETWEEN (NOW() - INTERVAL 7 DAY) AND NOW()
AND c.created_at BETWEEN (NOW() - INTERVAL 7 DAY) AND NOW()
AND b.`status` IN ('processing', 'complete', 'printed', 'ready_to_print', 'ready_to_ship')
AND c.parent_item_id IS NULL
AND c.sku LIKE 'D-%'
GROUP BY
b.created_at, store_id
ORDER BY hour_key DESC
I have this mysql function:
BEGIN
DECLARE top_tags VARCHAR(100) charset utf8;
SELECT substring_index(group_concat(x.NAME order BY x.tag_score DESC separator ','), ',', 5)
INTO top_tags
FROM (SELECT t.NAME, Sum(r.score) AS tag_score
FROM reputations r
JOIN qanda_tags qt ON qt.qanda_id = r.question_id
JOIN tags t ON t.id = qt.tag_id
WHERE r.owner_id = 1
AND r.date_time > CASE 'all'
WHEN 'WEEK' THEN unix_timestamp(date_sub(Now(), interval 1 week))
WHEN 'MONTH' THEN unix_timestamp(date_sub(now(), interval 1 month))
WHEN 'YEAR' THEN unix_timestamp(date_sub(now(), interval 1 year))
ELSE 1
END
group BY t.NAME ) x;
return top_tags;
end
It returns an empty result set:
And when I add limit 60 clause right after group BY t.NAME, it returns the expected result:
Why really?
Note: limit 61 or more causes no result either. limit 60 or less has the result.
I'm not sure, but would it be more efficient to do the filtering before the group_concat()?
SELECT group_concat(x.NAME order BY x.tag_score DESC separator ',')
INTO top_tags
FROM (SELECT t.NAME, Sum(r.score) AS tag_score
FROM reputations r JOIN
qanda_tags qt
ON qt.qanda_id = r.question_id JOIN
tags t
ON t.id = qt.tag_id
WHERE r.owner_id = 1 AND
r.date_time > (CASE 'all'
WHEN 'WEEK' THEN unix_timestamp(date_sub(Now(), interval 1 week))
WHEN 'MONTH' THEN unix_timestamp(date_sub(now(), interval 1 month))
WHEN 'YEAR' THEN unix_timestamp(date_sub(now(), interval 1 year))
ELSE 1
END)
group BY t.NAME
order by tag_score desc
limit 5
) x;
I have a query that fetch records from two table. I want if condition in where clause with and operator.
Here is my code :
SELECT sfo.customer_id, sfo.increment_id FROM sales_flat_order sfo
INNER JOIN marketplace_partnertype mptype ON sfo.customer_id = mptype.partner_id
WHERE (mptype.type = 'free' AND sfo.status='complete') AND IF #mptype.type=='free' THEN ((DATE( updated_at ) = DATE_SUB( CURDATE( ) , INTERVAL 5 DAY ))ELSE (DATE( updated_at ) = DATE_SUB( CURDATE( ) , INTERVAL 3 DAY );
It shows syntax error near IF #mptype.type=='free'.
It should be appreciable if some help to solve this issues.
Syntax of If condition is:
IF(<cond-expr>, <then-expr>, <else-expr>)
If we change the condition it will be like :-
AND IF (#mptype.type=='free', (DATE( updated_at ) = DATE_SUB( CURDATE( ) , INTERVAL 5 DAY )) ,(DATE( updated_at ) = DATE_SUB( CURDATE( ) , INTERVAL 3 DAY ))
Query will look like:
SELECT sfo.customer_id, sfo.increment_id FROM sales_flat_order sfo
INNER JOIN marketplace_partnertype mptype ON sfo.customer_id = mptype.partner_id
WHERE (mptype.type = 'free' AND sfo.status='complete')AND IF (#mptype.type=='free', (DATE( updated_at ) = DATE_SUB( CURDATE( ) , INTERVAL 5 DAY )) ,(DATE( updated_at ) = DATE_SUB( CURDATE( ) , INTERVAL 3 DAY )))
The syntax is not correct, you can use case-when condition in the where condition as
SELECT sfo.customer_id, sfo.increment_id FROM sales_flat_order sfo
INNER JOIN marketplace_partnertype mptype ON sfo.customer_id = mptype.partner_id
WHERE (mptype.type = 'free' AND sfo.status='complete')
and
case
when #mptype.type = 'free' then DATE( updated_at ) = DATE_SUB( CURDATE( ) , INTERVAL 5 DAY )
else DATE( updated_at ) = DATE_SUB( CURDATE( ) , INTERVAL 3 DAY )
end
There's no need to use IF or CASE WHEN:
SELECT
sfo.customer_id,
sfo.increment_id
FROM
sales_flat_order sfo INNER JOIN marketplace_partnertype mptype
ON sfo.customer_id = mptype.partner_id
WHERE
(mptype.type = 'free' AND DATE(updated_at) = DATE_SUB(CURDATE(), INTERVAL 5 DAY)
OR (mptype.type = 'complete' AND DATE(updated_at) = DATE_SUB(CURDATE(), INTERVAL 3 DAY);
but if you want to use case when you could do it this way:
WHERE
mptype.type IN ('free', 'complete')
AND DATE(updated_at) = DATE_SUB(CURDATE(), INTERVAL CASE WHEN mptype.type='free' THEN 3 ELSE 5 END DAY)
I have a query which looks like:
SELECT max(sp.id) as max_id, p.name as player, max(update_time) as last_seen, min(login_time) as first_seen, s.name as last_server,
sum(sp.play_time) as ontime_total,
sum(case when login_time > NOW() - INTERVAL 1 DAY then sp.play_time end) as ontime_day,
sum(case when login_time > NOW() - INTERVAL 7 DAY then sp.play_time end) as ontime_week,
sum(case when login_time > NOW() - INTERVAL 1 MONTH then sp.play_time end) as ontime_month
FROM session_player sp
INNER JOIN players p ON p.id=sp.player_id
INNER JOIN server s ON s.id=sp.server_id
WHERE p.name = ?
The result:
The issue:
Node22 isn't the last server. I am struggling on finding a way to get the server of the last record within this query. How would you solve this issue, if possible without running a second query.
(This query already takes 2-3s seconds depending on the user, if possible I would like to avoid any overhead and in case you see performance optimization possibilities I would appreciate anything.)
This would work, but its performance you can guess (4-5s):
SELECT
MAX( sp.id ) AS max_id, p.name AS player, MAX( update_time ) AS last_seen, MIN( login_time ) AS first_seen,
SUM( sp.play_time ) AS ontime_total,
SUM( CASE WHEN login_time > NOW( ) - INTERVAL 1 DAY THEN sp.play_time END ) AS ontime_day,
SUM( CASE WHEN login_time > NOW( ) - INTERVAL 7 DAY THEN sp.play_time END ) AS ontime_week,
SUM( CASE WHEN login_time > NOW( ) - INTERVAL 1 MONTH THEN sp.play_time END ) AS ontime_month,
(SELECT s.name
FROM session_player sp
JOIN players p ON p.id=sp.player_id
JOIN server s ON s.id=sp.server_id
WHERE p.name = ?
ORDER BY sp.id DESC
LIMIT 1
) as last_server
FROM session_player sp
INNER JOIN players p ON p.id = sp.player_id
INNER JOIN server s ON s.id = sp.server_id
WHERE p.name = ?
After nearly 3 hours of experimenting I got it and even 260 times faster as before:
SELECT MAX(pd.id) AS max_id, pd.name AS player, MAX( pd.update_time ) AS last_seen, MIN( pd.login_time ) AS first_seen,
SUM( pd.play_time ) AS ontime_total,
SUM( CASE WHEN pd.login_time > NOW( ) - INTERVAL 1 DAY THEN pd.play_time END ) AS ontime_day,
SUM( CASE WHEN pd.login_time > NOW( ) - INTERVAL 7 DAY THEN pd.play_time END ) AS ontime_week,
SUM( CASE WHEN pd.login_time > NOW( ) - INTERVAL 1 MONTH THEN pd.play_time END ) AS ontime_month,
(SELECT s.name
FROM session_player sp
INNER JOIN server s ON s.id=sp.server_id
WHERE max(pd.id)=sp.id
) as last_server
FROM (
SELECT sp.id AS id, sp.server_id as server_id, p.name AS name, sp.login_time AS login_time, sp.update_time AS update_time, sp.play_time AS play_time
FROM session_player sp
INNER JOIN players p ON p.id=sp.player_id
WHERE p.name = ?
) as pd
Try this:
SELECT sp.id as max_id, p.name as player, max(update_time) as last_seen,
min(login_time) as first_seen, s.name as last_server,
sum(sp.play_time) as ontime_total,
sum(case when login_time > NOW() - INTERVAL 1 DAY then sp.play_time end) as ontime_day,
sum(case when login_time > NOW() - INTERVAL 7 DAY then sp.play_time end) as ontime_week,
sum(case when login_time > NOW() - INTERVAL 1 MONTH then sp.play_time end) as ontime_month
FROM session_player sp
INNER JOIN players p ON p.id=sp.player_id
INNER JOIN server s ON s.id=sp.server_id
WHERE p.name = ?
group by sp.player_id
order by sp.id desc limit 1
Why wont my interval day work in mysql statement.
I want those who is more than 2 days old. This is how i tried.
SELECT t.*, ct.*,cd.*, max(t.transactiontime) as maxtime
FROM exp_channel_titles as ct
LEFT JOIN transactions as t on (ct.entry_id = t.restaurant_id)
LEFT JOIN exp_channel_data as cd on (ct.entry_id = cd.entry_id)
WHERE t.cardid > 0
and maxtime < ( CURDATE() - INTERVAL 2 DAY )
and t.restaurant_id > 0
and ct.status= 'open'
Group by ct.entry_id
order by maxtime desc
This is my current output
TransactionID Title TransactionTime
23132 Locaton 2013-05-17 10:02:04
23131 Novuel 2013-05-16 16:26:45
23128 Mama Rosa 2013-05-15 14:42:44
23126 Rohan 2013-05-14 12:46:56
This is my desired output
TransactionID Title Date
23128 Mama Rosa 2013-05-15 14:42:44
23126 Rohan 2013-05-14 12:46:56
But i am getting this error
Error Number: 1054
Unknown column 'maxtime' in 'where clause'
SELECT t.*, ct.*,cd.*, max(t.transactiontime) as maxtime FROM exp_channel_titles as ct LEFT JOIN transactions as t on (ct.entry_id = t.restaurant_id) LEFT JOIN exp_channel_data as cd on (ct.entry_id = cd.entry_id) WHERE t.cardid > 0 and maxtime < ( CURDATE() - INTERVAL 2 DAY ) and t.restaurant_id > 0 and ct.status= 'open' Group by ct.entry_id order by maxtime desc
Filename: libraries/Functions.php(656) : eval()'d code
Line Number: 46
Try:
maxtime < DATE_FORMAT( NOW() - INTERVAL 2 DAY ,'%Y-%m-%d 23:59:59')
CURDATE() returns DATE type and you need DATETIME type so you should use NOW()
in your query you use CURDATE but as I understand your date column is datetime data type so..
NOW() = 2008-11-11 12:45:34
CURDATE() = 008-11-11
CURTIME() = 12:45:34
this is what the mysql functions return. use the correct function here
maxtime < ( CURDATE() - INTERVAL 2 DAY )
change CURDATE() to NOW() but this my not be the solution for you. you need to find out.
You can not use alias name in where clause,used max(t.transactiontime)< ( now() - INTERVAL 2 DAY )