JSON SQL Query gives error on SET - php

$query = mysql_query(" SET #c1=0; SELECT #c1 := #c1+1 as Week,
AVG(Temp) AS Average_Temperature FROM ( SELECT t1.*, COUNT(*) cnt
FROM test2 t1 LEFT JOIN test2 t2
ON t2.Date <= t1.Date
AND YEAR(FROM_UNIXTIME(t2.Date)) = YEAR(FROM_UNIXTIME(t1.Date))
AND MONTH(FROM_UNIXTIME(t2.Date)) = MONTH(FROM_UNIXTIME(t1.Date)) GROUP
BY Date ) t GROUP BY YEAR(FROM_UNIXTIME(Date)), MONTH(FROM_UNIXTIME(Date)), CEIL(cnt/7);" );
If I dont use SET #c1=0; I got no error... So whats the use of this on json php? Above code successfully queried on PHPMyAdmin.
edit: solved

Just enclose them in quotes .. See here $query = mysql_query(" your query ");
Like this..
$query = mysql_query("
SELECT AVG(Temp) AS Average_Temperature FROM (
SELECT t1.*, COUNT(*) cnt FROM test2 t1
LEFT JOIN test2 t2
ON t2.Date <= t1.Date
AND YEAR(FROM_UNIXTIME(t2.Date)) = YEAR(FROM_UNIXTIME(t1.Date))
AND MONTH(FROM_UNIXTIME(t2.Date)) = MONTH(FROM_UNIXTIME(t1.Date))
GROUP
BY Date
) t
GROUP BY
YEAR(FROM_UNIXTIME(Date)), MONTH(FROM_UNIXTIME(Date)), CEIL(cnt/7);
");
Disclaimer : Stop using mysql_* functions as they are deprecated. Switch to MySQLi or PDO instead.

Clearly, the set and select are incompatible as a single query. There is an easy work-around. Set the variable in the query:
SELECT #c1 := #c1+1 as Week, AVG(Temp) AS Average_Temperature
FROM (SELECT t1.*, COUNT(*) as cnt
FROM test2 t1 LEFT JOIN
test2 t2
ON t2.Date <= t1.Date AND
YEAR(FROM_UNIXTIME(t2.Date)) = YEAR(FROM_UNIXTIME(t1.Date)) AND
MONTH(FROM_UNIXTIME(t2.Date)) = MONTH(FROM_UNIXTIME(t1.Date))
GROUP BY Date
) t cross join
(select #c1 := 0) const
GROUP BY YEAR(FROM_UNIXTIME(Date)), MONTH(FROM_UNIXTIME(Date)), CEIL(cnt/7);

Related

How Can I delete other duplicate values of same date by keeping last data in Laravel and mySql?

What I Have :
I have an 'items' table on Item Model where data are like -
id----item_id-----name------created_at
1-----1234------test1------2021-07-05 06:44:48
2-----1234------test1------2021-07-05 06:48:34
3-----1234------test1------2021-07-05 06:50:09
4-----1234------test1------2021-07-06 09:40:16
5-----1234------test1------2021-07-06 06:12:13
6-----1234------test1------2021-07-06 05:41:43
What I Want :
I want to delete duplicate data of same-day just keeping latest one.
id----item_id-----name------created_at
3-----1234------test1------2021-07-05 06:50:09
4-----1234------test1------2021-07-06 09:40:16
If I understand correctly you want id/date combinations where there is only one row. If so, you can use not exists:
select t.*
from t
where not exists (select 1
from t t2
where t2.item_id = t.item_id and
date(t2.created_at) = date(t.created_at) and
t2.id <> t.id
);
An alternative uses window functions:
select t.*
from (select t.*,
count(*) over (partition by item_id, date(created_at)) as cnt
from t
) t
where cnt = 1;
Check the below query, here I am selecting the latest timestamp from the table, in your case it is the created_date
SELECT T1.* FROM TABLE_NAME T1 INNER JOIN
(
SELECT MAX(CREATED_DATE) CREATED_DATE
FROM TABLE_NAME
GROUP BY DATE_FORMAT(CREATED_DATE, '%Y-%m-%d' )
) T2 ON T1.CREATED_DATE = T2.CREATED_DATE ;

How to use a SELECT statement into JOIN clause?

I have a variable which is containing a dynamic query. Something like this:
$query = "SELECT id, subject FROM post1
UNION ALL
SELECT id, subject FROM post2
UNION ALL
SELECT id, subject FROM post3";
Also I have this query:
SELECT code FROM mytable WHERE id = :id
Now I want to join query above with that dynamic query. Here is my try:
SELECT t1.code t2.subject FROM mytable t1
LEFT JOIN ($query) t2 ON t1.col = t2.id
WHERE t1.id = :id
/*
SELECT t1.code t2.subject FROM mytable t1
LEFT JOIN (SELECT id, subject FROM post1
UNION ALL
SELECT id, subject FROM post2
UNION ALL
SELECT id, subject FROM post3) t2 ON t1.col = t2.id
WHERE t1.id = :id
*/
It works. But it takes a lot of time for huge data. How can I make it faster?
SELECT t1.code t2.subject FROM mytable t1
LEFT JOIN (SELECT id, subject FROM post1
JOIN mytable tt1 ON tt1.col = post1.id AND tt1.id=:id
UNION ALL
SELECT id, subject FROM post2
JOIN mytable tt2 ON tt2.col = post2.id AND tt2.id=:id
UNION ALL
SELECT id, subject FROM post3
JOIN mytable tt3 ON tt3.col = post3.id AND tt3.id=:id) t2 ON t1.col = t2.id
WHERE t1.id = :id
Just add the :id check to the internal querie4st to restrict amount of data selected.
You can use below query.
SELECT t1.code, t2.subject FROM (SELECT code, col FROM mytable WHERE id = :id ) t1
LEFT JOIN ($query) t2 ON t1.col = t2.id

mysql query left join with newest date

I want to get the id from first table, and the information in the second table but only if there is any related row in second table, AND where the greatest date of the related rows is smaller(earlier) than time right now...
This is what I have right now:
"SELECT t1.id as actID, t2.id AS eventsid, t2.controlled FROM `activites` t1
LEFT JOIN `events` t2 ON t2.activitesid = t1.id
WHERE t2.datum < UNIX_TIMESTAMP() GROUP BY t2.controlled"
And what I have been trying is something like
"SELECT t1.id as actID, t2.id AS eventsid, t2.controlled FROM `activites` t1
LEFT JOIN `events` t2 ON t2.activitesid = t1.id
WHERE (SELECT `datum` FROM `events` t3 WHERE t3.controlled = t2.controlled ORDER BY `datum` DESC LIMIT 1) < UNIX_TIMESTAMP() GROUP BY t2.controlled"
Is there anybody who can point me in wich direction to go or how to type this kind of query?
There is no need pointing out that I should use PDO, mysqli etc...

mysql long time query

I have a query on my PHP script it takes too long time!
When I run the query, server load time increase and server goes down!
Note: these fields are index: t1.submits_id,t4.submit_id,t3.userid,t1.user_id,owner_id,invited_id,agreed,t2.users_id,,t1.sent_timestamp
SELECT
t1.submits_id,t1.user_id,is_html,shared_from,type,contents,url,sent_timestamp,show_type,album_cached_info,
t2.users_id,name,t2.active,page_url,
t3.time,
t4.like_time
FROM iv6_submits as t1 LEFT JOIN iv6_likes as t4 ON (t1.submits_id = t4.submit_id AND t4.user_id=1)
,iv6_users as t2 LEFT JOIN iv6_onlineusers as t3 ON (t2.users_id=t3.userid)
WHERE
t1.submits_id<19000 AND
(t1.user_id=1 OR t1.user_id in
(select IF(owner_id=1,invited_id,owner_id) as id
from iv6_add_lists
where ((owner_id=1 or invited_id=1) AND agreed=1) OR (owner_id=1 AND agreed=2)))
AND t2.users_id=t1.user_id
ORDER BY t1.sent_timestamp DESC LIMIT 10
I'd start by writing the query as:
SELECT t1.submits_id,
t1.user_id,
is_html, /* I'd append all table aliases here */
shared_from,
type,
contents,
url,
sent_timestamp,
show_type,
album_cached_info,
t2.users_id,
name,
t2.active,page_url,
t3.time,
t4.like_time
FROM iv6_submits as t1
JOIN iv6_users as t2
ON t2.users_id=t1.user_id
LEFT JOIN iv6_likes as t4
ON t4.submit_id = t1.submits_id
AND t4.user_id=1
LEFT JOIN iv6_onlineusers as t3
ON t3.userid = t2.users_id
WHERE t1.submits_id<19000
AND (
t1.user_id=1
OR t1.user_id IN (
SELECT IF(owner_id=1,invited_id, owner_id) as id
FROM iv6_add_lists
WHERE ((owner_id=1 OR invited_id=1) AND agreed=1)
OR (owner_id=1 AND agreed=2))
)
ORDER BY t1.sent_timestamp DESC
LIMIT 10
From this and your explain i'd guess that t1.submits_id< 19000 reduces your result set the most. So I'd then try:
...
FROM iv6_submits as t1 USE INDEX (submits_id)
...
Your subquery is also v. strange, i'd rewrite it as something like:
SELECT invited_id
FROM iv6_add_lists
WHERE owner_id = 1
AND agreed BETWEEN 1 AND 2
UNION ALL
SELECT owner_id
FROM iv6_add_lists
WHERE invited_id = 1
AND agreed = 1
AND owner_id != 1
And see if that helps as well, you can hint an index for each FROM. A composite index on (owner_id, agreed, invited_id) and (invited_id, agreed, owner_id) should cover both queries respectively.
You also could write this as
SELECT 1
UNION
SELECT DISTINCT invited_id
FROM iv6_add_lists
WHERE owner_id = 1
AND agreed BETWEEN 1 AND 2
UNION
SELECT DISTINCT owner_id
FROM iv6_add_lists
WHERE owner_id != 1
AND agreed = 1
AND invited_id = 1
And JOIN it to your t1 instead of the AND (t1.user_id=1 OR ...)
UPDATE
SELECT t1.submits_id,
t1.user_id,
is_html, /* I'd append all table aliases here */
shared_from,
type,
contents,
url,
sent_timestamp,
show_type,
album_cached_info,
t2.users_id,
name,
t2.active,page_url,
t3.time,
t4.like_time
FROM iv6_submits as t1
JOIN iv6_users as t2
ON t2.users_id=t1.user_id
JOIN (
SELECT 1 user_id
UNION
SELECT DISTINCT invited_id
FROM iv6_add_lists
WHERE owner_id = 1
AND agreed BETWEEN 1 AND 2
UNION
SELECT DISTINCT owner_id
FROM iv6_add_lists
WHERE owner_id != 1
AND agreed = 1
AND invited_id = 1
) t5
ON t1.user_id = t5.user_id
LEFT JOIN iv6_likes as t4
ON t4.submit_id = t1.submits_id
AND t4.user_id=1
LEFT JOIN iv6_onlineusers as t3
ON t3.userid = t2.users_id
WHERE t1.submits_id<19000
ORDER BY t1.sent_timestamp DESC
LIMIT 10
I suggest you split the query to see where the resources are being consumed.
Execute the subquery in the WHERE section and see if it runs fast
Remove the left joins and then add one by one to see where it all goes down.
Remove all the "WHERE" conditions and add one by one.
Try to run the query without the "ORDER BY" statement.
You did not referred t4.user_id as being indexed, it may be important.
Table iv6_add_lists also should have all the fields present in WHERE statement indexed.
Also suggest you to make an INNER JOIN between t1 and t2:
FROM (iv6_submits as t1
LEFT JOIN iv6_likes as t4 ON (t1.submits_id = t4.submit_id AND t4.user_id=1))
INNER JOIN
(iv6_users as t2
LEFT JOIN iv6_onlineusers as t3 ON (t2.users_id=t3.userid))
ON t2.users_id=t1.user_id
Then ou can remove
AND t2.users_id=t1.user_id
from the WHERE statement.
Try This.
SELECT
t1.submits_id,t1.user_id,is_html,shared_from,type,contents,url,sent_timestamp,show_type,album_cached_info,
t2.users_id,name,t2.active,page_url,
t3.time,
t4.like_time
FROM
iv6_submits as t1
LEFT JOIN iv6_users as t2 ON t2.users_id = t1.user_id
LEFT JOIN iv6_likes as t4 ON t1.submits_id = t4.submit_id AND t4.user_id = 1
LEFT JOIN iv6_onlineusers as t3 ON t2.users_id = t3.userid
WHERE
t1.submits_id < 19000
AND
(t1.user_id = 1 OR t1.user_id in
(
select IF(owner_id=1,invited_id,owner_id) as id from iv6_add_lists where (invited_id=1 AND agreed=1) OR ( owner_id=1 AND agreed IN (1,2) )
)
)
ORDER BY t1.sent_timestamp DESC LIMIT 1

using HAVING with another tables record COUNT

I am trying to count row numbers on an another table and use HAVING to select only rows greater than 0.
SELECT COUNT(t3.ID),t1.ID,t2.sell,t1.date
FROM `album` t1
INNER JOIN `members` t2 ON t2.aID = t1.ID
INNER JOIN `table` t3 ON t3.rID = t1.ID
WHERE t1.date <= '$dt' AND t2.sell = '1'
ORDER BY t1.date DESC
HAVING COUNT(t3.ID) > 0
It doesnt work. where am i wrong ?
Thanks
You need a GROUP BY clause so that MySQL knows how to group the data when you're using aggregate functions such as COUNT.
SELECT COUNT(t3.ID),t1.ID,t2.sell,t1.date
FROM `album` t1
INNER JOIN `members` t2 ON t2.aID = t1.ID
INNER JOIN `table` t3 ON t3.rID = t1.ID
WHERE t1.date <= '$dt' AND t2.sell = '1'
GROUP BY t1.ID,t2.sell,t1.date
HAVING COUNT(t3.ID) > 0
ORDER BY t1.date DESC
For more information, see this.

Categories