Mysql UNION Tables MAX date - mysql

I have two tables calls and tasks. I want to get the farthest date which ever is from both tables. The result will be one date that is the Maximum of all.
So basically want to join the quires below
SELECT id, MAX(date_due) FROM tasks WHERE
parent_id = '35'
AND date_due > CURDATE()
SELECT id, MAX(date_start) FROM calls WHERE
parent_id = '35'
AND date_start > CURDATE()
These will result the max date from each table but how do i get single record which is the Highest Date.

If you want the greatest value from MAX(date_due) and MAX(date_start)
add an alias to your MAX function
use an UNION between your two queries
use that UNIONed query as a subquery.
select id, MAX(mx) FROM
(SELECT id, MAX(date_due) as mx FROM tasks WHERE parent_id = '35' AND date_due > CURDATE()
UNION
SELECT id, MAX(date_start) as mx FROM calls WHERE parent_id = '35' AND date_start > CURDATE()) s

Related

How do I select data going back a period of time for each group?

I want for each group id to get the latest week's worth of data. Not from a specific date, but counting backwards from the MAX(startTime) of each individual group.
However, the following does not seem to work. I assume it's because startTime in each group (a single value) is BETWEENed by itself? Otherwise, how do I keep it in my filter?
SELECT
id
, startTime
FROM MyTable
GROUP BY id, startTime
HAVING startTime BETWEEN MAX(startTime) - INTERVAL 1 WEEK AND MAX(startTime)
What's the right query?
Also, in my case it has to work with MySQL 5.7.
SELECT m.id, m.startTime
FROM (
SELECT id, MAX(startTime) AS startTime
FROM MyTable GROUP BY id
) AS x
JOIN MyTable AS m ON m.id = x.id
AND m.startTime BETWEEN x.startTime - INTERVAL 1 WEEK AND x.startTime;

Getting the last and oldest price of a grouped row

I have this query and I want to select the currentprice(the most current price sorted by time) and the oldprice(the last row sorted by time) in the same columns per row. I figured out how to select the currentprice but how can I select both in the same query?
In the end I want to make a calculation for the percentage of gain or drop with ROUND((latestprice - oldprice) / oldprice * 100, 2) as gain_ratio
WITH tmp AS (
SELECT TrackID, ID, price, MAX(Time) as maxtime, MIN(Time) as mintime
FROM track
WHERE Time > NOW() - INTERVAL 1 HOUR
GROUP BY ID
)
SELECT T.TrackID, T.ID, tmp.Price as currentprice, T.Time
FROM track AS T
JOIN tmp ON T.ID = tmp.ID
WHERE T.Time = tmp.maxtime;
I'm really struggeling to grasp how to make a CTE query, I have read the documentation several times
Have you tried to change your where clause to...?:
WHERE T.Time = tmp.maxtime or T.Time = tmp.mintime

Combine 2 sql queries into 1 query

I have 2 queries right now for which I am looking to combine into 1 if possible.
I have open tickets stored in the Tickets_Open table and closed tickets in Tickets_Closed. Both tables have "Date_Requested" and "Date_Completed" columns. I need to count the number of tickets requested and completed each day.
My tickets requested count query is the following:
SELECT SUM(Count) AS TotalOpen, Date FROM(
SELECT COUNT(Ticket_Request_Code) AS Count, Date_Requested AS Date
FROM Tickets_Closed
WHERE Date_Requested >='2018-01-01 00:00:00'
GROUP BY(Date_Requested)
UNION
SELECT COUNT(Work_Request_Code) AS Count, Date_Requested AS Date
FROM Tickets_Open
WHERE Date_Requested >='2018-01-01 00:00:00'
GROUP BY(Date_Requested)
) AS t1 GROUP BY Date ORDER BY `t1`.`Date` DESC
My tickets completed count query is the following:
SELECT COUNT(Ticket_Request_Code) AS CountClosed, Date_Completed AS Date
FROM Tickets_Closed
Where Date_Completed >='2018-01-01 00:00:00'
GROUP BY(Date_Completed)
Both queries return the correct result. For open it returns with the column headings Date and TotalOpen. For close it returns with the column headings Date and CountClosed.
Is it possible to return it with the following column headings Date, TotalOpen, CountClosed.
You can combine these as:
SELECT Date, SUM(isopen) as isopen, SUM(isclose) as isclose
FROM ((SELECT date_requested as date, 1 as isopen, 0 as isclose
FROM Tickets_Closed
WHERE Date_Requested >= '2018-01-01'
) UNION ALL
(SELECT date_requested, 1 as isopen, 0 as isclose
FROM Tickets_Open
WHERE Date_Requested >= '2018-01-01'
) UNION ALL
(SELECT date_closed as date, 0 as isopen, 1 as isclose
FROM Tickets_Closed
WHERE date_closed >= '2018-01-01'
)
) t
GROUP BY Date
ORDER BY Date DESC;
This assumes that Ticket_Request_Code and Work_Request_Code are not NULL. If COUNT() is really being used to check for NULL values, then add the condition to the WHERE clause in each subquery.
This query uses the FULL OUTER JOIN on the Dates as well, but it correctly adds the Open/Closed counts together to give you a TotalOpen Count. This will also handle possible NULL values for cases where you have a day that doesn't close any tickets.
WITH open AS
(
SELECT COUNT(Work_Request_Code) AS OpenCount, Date_Requested AS Date
FROM Tickets_Open
WHERE Date_Requested >='2018-01-01 00:00:00'
GROUP BY(Date_Requested)
)
, close AS
(
SELECT COUNT(Ticket_Request_Code) AS ClosedCount, Date_Requested AS Date
FROM Tickets_Closed
WHERE Date_Requested >='2018-01-01 00:00:00'
GROUP BY(Date_Requested)
)
SELECT
COALESCE(c.Date, o.Date) AS Date
, IFNULL(o.OpenCount, 0) + IFNULL(c.ClosedCount, 0) AS TotalOpen
, IFNULL(c.CountClosed, 0) AS CountClosed
FROM open o
FULL OUTER JOIN closed c ON o.Date = c.Date

How to Group a table and get results for a row based on the previous rows' data

I have a lookup table that relates dates and people associated with those dates:
id, user_id,date
1,1,2014-11-01
2,2,2014-11-01
3,1,2014-11-02
4,3,2014-11-02
5,1,2014-11-03
I can group these by date(day):
SELECT DATE_FORMAT(
MIN(date),
'%Y/%m/%d 00:00:00 GMT-0'
) AS date,
COUNT(*) as count
FROM user_x_date
GROUP BY ROUND(UNIX_TIMESTAMP(created_at) / 43200)
But, how can get the number of unique users, that have now shown up previously? For instance this would be a valid result:
unique, non-unique, date
2,0,2014-11-01
1,1,2014-11-02
0,1,2014-11-03
Is this possibly without having to rely on a scripting language to keep track of this data?
I think this query will do what you want, at least it seems to work for your limited sample data.
The idea is to use a correlated sub-query to check if the user_id has occurred on a date before the date of the current row and then do some basic arithmetic to determine number of unique/non-unique users for each date.
Please give it a try.
select
sum(u) - sum(n) as "unique",
sum(n) as "non-unique",
date
from (
select
date,
count(user_id) u,
case when exists (
select 1
from Table1 i
where i.user_id = o.user_id
and i.date < o.date
) then 1 else 0
end n
from Table1 o
group by date, user_id
) q
group by date
order by date;
Sample SQL Fiddle
I didn't include the id column in the sample fiddle as it's not needed (or used) to produce the result and won't change anything.
This is the relevant question: "But, how can get the number of unique users, that have now shown up previously?"
Calculate the first time a person shows up, and then use that for the aggregation:
SELECT date, count(*) as FirstVisit
FROM (SELECT user_id, MIN(date) as date
FROM user_x_date
GROUP BY user_id
) x
GROUP BY date;
I would then use this as a subquery for another aggregation:
SELECT v.date, v.NumVisits, COALESCE(fv.FirstVisit, 0) as NumFirstVisit
FROM (SELECT date, count(*) as NumVisits
FROM user_x_date
GROUP BY date
) v LEFT JOIN
(SELECT date, count(*) as FirstVisit
FROM (SELECT user_id, MIN(date) as date
FROM user_x_date
GROUP BY user_id
) x
GROUP BY date
) fv
ON v.date = fv.date;

Mysql Union Query Record result emptys column

I have a union query to get a Max date record from two tables
SELECT
id,
MAX(mx) AS max_date,
`assigned_user_id`
FROM (SELECT
id,
MAX(date_due) AS mx,
`assigned_user_id`
FROM tasks
WHERE `deleted` = 0
AND `parent_id` = 'aa6f0330-7a17-572f-94b5-4a5db1a1201f'
AND `parent_type` = 'Accounts'
AND date_due >= CURDATE() UNION SELECT
id,
MAX(date_start) AS mx,
`assigned_user_id`
FROM calls
WHERE `deleted` = 0
AND `account_id` = 'aa6f0330-7a17-572f-94b5-4a5db1a1201f'
AND date_start >= CURDATE()) s
this would look into both calls and Tasks and get me the Futuristic Call or a Task, but when i run this and i have a Futuristic Call and task is older, i get NULL in id and assigned_user_id columns. How do i fetch the whole info for the MAX date record.
When i Run individual Queries, i get null for first one while a record in the second one.
Perhaps I'm misreading the problem, or I'm missing something - in which case, write me a comment to let me know, and I can delete this post altogether.
But, the way I understand what you've written, you want to:
Get the single record in tasks with the given parent_id and parent_type and where date_due >= CURDATE() which has the latest date_due value.
Get that same type of record from the calls table (using date_start instead of date_due).
Of those two records, find the one record with the later date value. Select the id, the date (as max_date), and the assigned_user_id from that record.
Your query (and sub-queries) could just order by descending date and fetch only the first record.
I'm thinking something like this...
SELECT id,
mx AS max_date,
`assigned_user_id`
FROM (
SELECT id,
date_due as mx,
`assigned_user_id`
FROM tasks
WHERE `deleted` = 0
AND `parent_id` = 'aa6f0330-7a17-572f-94b5-4a5db1a1201f'
AND `parent_type` = 'Accounts'
AND date_due >= CURDATE()
ORDER BY date_due DESC
LIMIT 1
UNION
SELECT id,
date_start as mx,
`assigned_user_id`
FROM calls
WHERE `deleted` = 0
AND `account_id` = 'aa6f0330-7a17-572f-94b5-4a5db1a1201f'
AND date_start >= CURDATE()
ORDER BY date_start DESC
LIMIT 1
)
ORDER BY max_date DESC
LIMIT 1
Use UNION ALL. To allow duplicate values, use the ALL keyword with UNION.
Select Max(max_date) from
(SELECT
id,
MAX(mx) AS max_date,
assigned_user_id
FROM
(SELECT
id,
MAX(date_due) AS mx,
assigned_user_id
FROM tasks
WHERE deleted = 0
AND parent_id = 'aa6f0330-7a17-572f-94b5-4a5db1a1201f'
AND parent_type = 'Accounts'
AND date_due >= CURDATE() group by id UNION SELECT
id,
MAX(date_start) AS mx,
assigned_user_id
FROM calls
WHERE deleted = 0
AND account_id = 'aa6f0330-7a17-572f-94b5-4a5db1a1201f'
AND date_start >= CURDATE()) s group by id)
as temp