Query two tables with mysql to count total topics by hour - mysql

my forum have two tables to store topics (posts and forums_archive_posts)
$this->DB->build( array(
'select' => "HOUR( FROM_UNIXTIME( post_date ) ) as hour, COUNT(*) AS postCount",
'from' => 'posts',
'where' => "new_topic=0 AND author_id=" . $member['member_id'],
'group' => 'HOUR( FROM_UNIXTIME( post_date ) )',
) );
This query works only with the first table (posts), I need a query that works also in "forum_archive_posts"
tables structure (forum_archive_posts=posts):
archive_author_id = author_id
archive_content_date = post_date

No idea of how you do it in that format but something like
Select postHour, sum(postcount) as postCount From
(
select Hour ... as PostHour
From
Posts...
Union
Select Hour ...
From
ForumArchivePosts ...
) dummyTableName
Group by PostHour
should do the job. the do count bny hoiurs from both tables, then add them together.

Related

Get 2 Previous and Next with Current entry from database in laravel

I'm showing the image on a page. I am getting data with this
$designs = Design::take(10)->where('show', '1')->where('id', $id)->orderBy('hit', 'desc')->get();
Now I want 2 previous and 2 next records so users can select and see them.
Something like
Select 5 entry where the middle should be 'id'
The solution I came up with is the following:
You find the middle design.
Using it's id, you can get the previous 2 and make an union with a similar query that gets the next 2 (along with the original).
$design = Design::select('id')
->where('name', 'Sunset')
->firstOrFail();
$designs = Design::query()
->where('id', '<', $design->id)
->orderByDesc('id')
->limit(2)
->union(
Design::query()
->where('id', '>=', $design->id)
->orderBy('id')
->limit(3)
)
->orderBy('id')
->get();
The SQLs generated by this query are the following:
SELECT `id` FROM `designs`
WHERE `name` = "Sunset"
LIMIT 1
(
SELECT * FROM `designs`
WHERE `id` < ?
ORDER BY `id` DESC
LIMIT 2
)
UNION
(
SELECT * FROM `designs`
WHERE `id` >= ?
ORDER BY `id` ASC
LIMIT 3
)
ORDER BY `id` ASC
... Or if you'd rather have the results more separated
$design = Design::where('name', 'Sunset-Image')->firstOrFail();
$previous = Design::where('id', '<', $design->id)->orderByDesc('id')->limit(2)->get();
$next = Design::where('id', '>', $design->id)->orderBy('id')->limit(2)->get();

Laravel raw select with avg - cannot display fetched data

I have Laravel project and I want to fetch avg time. Select statement is correct but I can not display data because I get error: Array to string conversion
This is my code:
$limit = (int)$this->argument('distance');
$avgTimeBetweenBlocks = DB::select('SELECT AVG(b.timediff)
FROM
(
SELECT a.created_at, a.created_at_end, AVG(TIME_TO_SEC(TIMEDIFF(a.created_at, a.created_at_end))) AS timediff
FROM
(
SELECT created_at,
(
SELECT max( created_at)
FROM block_differences bd1
WHERE bd1.created_at < bd.created_at
) as created_at_end
FROM block_differences bd
limit :limit
) a
WHERE a.created_at_end is not null
GROUP BY a.created_at, a.created_at_end
) b', ['limit' => $limit] )->get();
echo json_decode(json_encode($avgTimeBetweenBlocks[0]), true);
$this->info("avgTimeBetweenBlocks {$avgTimeBetweenBlocks[0]} seconds");
I tried to display value in different way, but all the time I get the same result.
You're trying to echo an array here json_decode will convert it an array so echo will not work. use print_r instead of echo
print_r(json_decode(json_encode($avgTimeBetweenBlocks[0]), true));
Edit :- Array ( [AVG(b.timediff)] => 139.38775510 )
you've to change your query. check here I give you an example below.
$avgTimeBetweenBlocks = DB::select('SELECT AVG(b.timediff) as avgtimediff
FROM
(
SELECT a.created_at, a.created_at_end, AVG(TIME_TO_SEC(TIMEDIFF(a.created_at, a.created_at_end))) AS timediff
FROM
(
SELECT created_at,
(
SELECT max( created_at)
FROM block_differences bd1
WHERE bd1.created_at < bd.created_at
) as created_at_end
FROM block_differences bd
limit :limit
) a
WHERE a.created_at_end is not null
GROUP BY a.created_at, a.created_at_end
) b', ['limit' => $limit] )->get();
$response = json_decode(json_encode($avgTimeBetweenBlocks[0]), true);
echo $response['avgtimediff'];

Mysql count query by Grouping Year and Month horizontal

I am new to mysql query and i am stuck on getting query. Basically, i want the date to group as Year and month (Jan'17, Feb'17...) in horizontal way (column) as shown in Image below.
Data are shown in image below:
Please help to create query.
You can do conditional aggregation - once per login_id and then overall and then union both the results.
Select login_idindex,
Sum(date_format(visitdate, '%Y%m') = '201701' ) as jan_17,
Sum(date_format(visitdate, '%Y%m') = '201702' ) as feb_17,
. . .,
Count(*) as total
From your_table
Where visitdate between ? and ?
Group by login_idindex
Union all
Select null,
Sum(date_format(visitdate, '%Y%m') = '201701' ) as jan_17,
Sum(date_format(visitdate, '%Y%m') = '201702' ) as feb_17,
. . .,
Count(*) as total
From your_table
Where visitdate between ? and ?;
Replace ? with actual dates or remove the where clause if you are working with all the dates.

Assistance with a complex MySQL SQL Query

I hope this is the appropriate forum to ask for assistance. I have an SQL Query (MySQL) that is not returning the correct records in a Date Range (between two dates). I am happy to answer questions in relation to the query, however if anyone can make suggestions or correct the SQL Query that would be an excellent learning exercise. Thank you.
$raw_query = sprintf("SELECT
swtickets.ticketid AS `Ticket ID`,
swtickettimetracks.tickettimetrackid AS `Track ID`,
swtickets.ticketmaskid AS `TicketMASK`,
(
SELECT
swcustomfieldvalues.fieldvalue
FROM
swcustomfieldvalues,
swcustomfields
WHERE
swcustomfieldvalues.customfieldid = swcustomfields.customfieldid
AND swtickets.ticketid = swcustomfieldvalues.typeid
AND swcustomfields.title = 'Member Company'
ORDER BY
swcustomfieldvalues.customfieldvalueid DESC
LIMIT 1
) AS MemberCompany,
(
SELECT
swcustomfieldvalues.fieldvalue
FROM
swcustomfieldvalues,
swcustomfields
WHERE
swcustomfieldvalues.customfieldid = swcustomfields.customfieldid
AND swtickets.ticketid = swcustomfieldvalues.typeid
AND swcustomfields.title = 'Member Name'
ORDER BY
swcustomfieldvalues.customfieldvalueid DESC
LIMIT 1
) AS MemberName,
(
SELECT
swcustomfieldvalues.fieldvalue
FROM
swcustomfieldvalues,
swcustomfields
WHERE
swcustomfieldvalues.customfieldid = swcustomfields.customfieldid
AND swtickets.ticketid = swcustomfieldvalues.typeid
AND swcustomfields.title = 'Chargeable'
AND
swcustomfieldvalues.fieldvalue = '40'
ORDER BY
swcustomfieldvalues.customfieldvalueid ASC
LIMIT 1
) AS `Chg`,
swtickets.`subject` AS `Subject`,
swtickets.departmenttitle AS Category,
FROM_UNIXTIME(
swtickettimetracks.workdateline
) AS `workDateline`,
FROM_UNIXTIME(
swtickettimetracks.dateline
) AS `dateline`,
swtickettimetracks.timespent AS `Time Spent`,
swtickets.timeworked AS `Time Worked`
FROM
swtickets
INNER JOIN swusers ON swtickets.userid = swusers.userid
INNER JOIN swuserorganizations ON swuserorganizations.userorganizationid = swusers.userorganizationid
INNER JOIN swtickettimetracks ON swtickettimetracks.ticketid = swtickets.ticketid
WHERE
swuserorganizations.organizationname = '%s'
AND (
swtickets.ticketstatustitle = 'Closed'
OR swtickets.ticketstatustitle = 'Completed'
)
AND FROM_UNIXTIME(`workDateline`) >= '%s' AND FROM_UNIXTIME(`workDateline`) <= '%s'
ORDER BY `Ticket ID`,`Track ID`",
$userOrganization,
$startDate,
$endDate
);
As I mentioned, the Query works - however it does not return the records correctly between the two dates.
However, IF I run this simple query against the database :
SELECT swtickettimetracks.tickettimetrackid,
swtickettimetracks.ticketid,
swtickettimetracks.dateline,
swtickettimetracks.timespent,
swtickettimetracks.timebillable,
FROM_UNIXTIME(swtickettimetracks.workdateline)
FROM swtickettimetracks
WHERE FROM_UNIXTIME(swtickettimetracks.workdateline) >= '2013-04-16' AND FROM_UNIXTIME(swtickettimetracks.workdateline) <= '2013-04-18'
I get the correct date range returned. Help? Thank you in anticipation.
Edward.
Unless you are overthinking it, it's all in your different query WHERE clauses...
Your complex query returning the wrong results has
(join conditions between other tables)
AND swuserorganizations.organizationname = '%s'
AND ( swtickets.ticketstatustitle = 'Closed'
OR swtickets.ticketstatustitle = 'Completed' )
AND FROM_UNIXTIME(`workDateline`) >= '%s'
AND FROM_UNIXTIME(`workDateline`) <= '%s'
Your Other query has
FROM swtickettimetracks
WHERE FROM_UNIXTIME(swtickettimetracks.workdateline) >= '2013-04-16'
AND FROM_UNIXTIME(swtickettimetracks.workdateline) <= '2013-04-18'
So I would consider a few things. The first where has
FROM_UNIXTIME >= '%s' and FROM_UNIXTIME <= '%s'
Are you sure the '%s' values are properly formatted to match the '2013-04-16' and '2013-04-18' format sample?
But more importantly, your first query is using the same date range (if correct), but is also only getting those for specific organization name AND (Closed or Completed) records. So, if the second query is returning 100 records, but the main query only 70, then are the other 30 some status other than closed/completed, or a different organization? In addition, if the join tables don't have matching IDs that would prevent those with invalid IDs from being returned. The only way to confirm that is to change to LEFT-JOIN syntax on those tables and see the results.

mysql sum from two databases

SELECT db1.table.listener,
db2.table.listener,
SEC_TO_TIME( SUM( TIME_TO_SEC( db2.table.time ) ) + ( TIME_TO_SEC( db1.table.time ) ) ),
count( db2.table.listener )
FROM table
INNER JOIN db2.table
ON db1.table.listener = db2.table.listener
WHERE db2.table.ldate = '19.02.2013'
AND db1.table.ldate = '19.02.2013'
GROUP BY db2.table.listener, db1.table.listener
I have two tables in two different databases with same columns (listener,time,ldate). I need to sum times and group by listener. This query gives multiple records, i need only "listener, total time, number of listens". How can i do this with one query?
Desired result;
| listeners (from both table, full join) | count of values (from both table) | sum of time (from both table) |
See following:
SELECT db1.table.listener,
SEC_TO_TIME( SUM( TIME_TO_SEC( db2.table.time ) ) +
( TIME_TO_SEC( db1.table.time ) ) ),
count( db1.table.listener )
FROM table
INNER JOIN db2.table
ON db1.table.listener = db2.table.listener
WHERE db1.table.ldate = '19.02.2013'
GROUP BY db1.table.listener