Declare variables MySQL - php

I am trying to declare variables and run the query like this:
$sql = "SELECT #dateconsult := (YEARWEEK('2018-10-01',3)),
#countunits := ( SELECT COUNT(s.id_production)
FROM sw_sowing
WHERE status != 0
AND YEARWEEK(date,3) <= #dateconsult
GROUP BY id_production_unit_detail
),
#quadrants := ( SELECT DISTINCT value
FROM cf_config
WHERE parameter = 'PLANTHEALTH'
);
SELECT FORMAT(((count_quadrant * 100)/(total_units * Cuadrantes)),3) AS incidence
FROM (
SELECT #countunits AS total_units, #quadrants AS Cuadrantes,
FROM ph_planthealth
INNER JOIN ph_planthealth_detail ON ph_planthealth_detail.id_p = ph_planthealth.id
WHERE YEARWEEK(ph_planthealth.date,3) = #dateconsult
AND ph_planthealth.status = 200
AND ph_planthealth.id_tenant = 1
AND ph_planthealth_detail.id_plague != 0
GROUP BY ph_planthealth_detail.id_plague
) AS s
ORDER BY incidence DESC; ";
$plague = $this->db->fetchAll($sql, Phalcon\Db::FETCH_ASSOC, $options) ";
the problem is that it shows the result of the first SELECT which are the variables that I declared and not the one of the second SELECT that is the main query.
It's the first time I declare variables and I do not know if I'm doing it right.
I appreciate your comments and help regarding this topic.

You don't need to do the variable assignments in a separate SELECT. You can do them by joining with the main query.
SELECT FORMAT(((count_quadrant * 100)/(total_units * Cuadrantes)),3) AS incidence
FROM (
SELECT #countunits AS total_units, #quadrants AS Cuadrantes,
FROM ph_planthealth
INNER JOIN ph_planthealth_detail ON ph_planthealth_detail.id_p = ph_planthealth.id
WHERE YEARWEEK(ph_planthealth.date,3) = #dateconsult
AND ph_planthealth.status = 200
AND ph_planthealth.id_tenant = 1
AND ph_planthealth_detail.id_plague != 0
GROUP BY ph_planthealth_detail.id_plague
) AS s
CROSS JOIN (
SELECT #dateconsult := (YEARWEEK('2018-10-01',3)),
#countunits := ( SELECT COUNT(s.id_production)
FROM sw_sowing
WHERE status != 0
AND YEARWEEK(date,3) <= #dateconsult
GROUP BY id_production_unit_detail
),
#quadrants := ( SELECT DISTINCT value
FROM cf_config
WHERE parameter = 'PLANTHEALTH'
)
) AS vars
ORDER BY incidence DESC

Related

Trying to get multiple results with nested select statements

I'm trying to get this statement to return multiple rows (one for each campaign ID). This code was originally intended for only accepting one campaign ID, but I'm needing to involve it to accepting multiple campaign IDs. The following code snippet only returns 1 row, but should be returning 6 rows. I'd also assume this statement could be more efficient.
SELECT * FROM
(SELECT
campaignID,
count(ctaS.engagementID) AS numEngagements,
count(distinct(ctaS.targetID)) AS numTargets,
SUM(engagementType='email') AS numEmails,
SUM(engagementType='call') as numCalls,
SUM(engagementType='meeting') as numMeetings,
count(distinct(ctaC.email)) AS numEngagementsByEmail,
count(distinct(ctaS.ipAddress)) AS numEngagementsByIP
FROM engagements AS ctaS
LEFT JOIN engagements_content AS ctaC ON ctaS.engagementID = ctaC.engagementID
WHERE ctaS.campaignID IN ('639ba3c9d86726f2ef5a6ca3','2bce996549ed7acb','f91491361140ccd81a7ab8bb','3d4d9a45bba4b8ef9c22edbc','VhFfwsAnxr9OBfRvGWKsyr7H','0819c9ff210c24f9efcb16fc')
AND ctaS.is_active = 1
AND ctaS.targetID <> ''
AND ctaS.engagementType <> ''
AND ctaS.ipAddress NOT IN ('75.43.48.211')
) as tbl1,
(SELECT
t1.numTimesIndexLoaded,
t1.numTimesIndexLoadedUnique,
t1.numTimesResultsLoaded,
t1.numTimesResultsLoadedUnique,
t1.numTimesCTALoaded,
t1.numTimesCTALoadedUnique
FROM
(SELECT sum(ctaSL.page = 'index') AS numTimesIndexLoaded,
sum(ctaSL.page = 'results') AS numTimesResultsLoaded,
sum(ctaSL.page = 'cta') AS numTimesCTALoaded,
count(DISTINCT CASE WHEN ctaSL.page = 'index' THEN ctaSL.ip_address END) AS numTimesIndexLoadedUnique,
count(DISTINCT CASE WHEN ctaSL.page = 'results' THEN ctaSL.ip_address END) AS numTimesResultsLoadedUnique,
count(DISTINCT CASE WHEN ctaSL.page = 'cta' THEN ctaSL.ip_address END) AS numTimesCTALoadedUnique
FROM stats_page_loads AS ctaSL
WHERE ctaSL.campaign_id IN ('639ba3c9d86726f2ef5a6ca3','2bce996549ed7acb','f91491361140ccd81a7ab8bb','3d4d9a45bba4b8ef9c22edbc','VhFfwsAnxr9OBfRvGWKsyr7H','0819c9ff210c24f9efcb16fc')
AND ctaSL.is_active = 1
AND ctaSL.ip_address NOT IN ('75.43.48.211')
) t1
) as tbl2,
(SELECT tblA.numFacebookClicks, tblB.numTwitterClicks
FROM
(SELECT count(target_id) AS numFacebookClicks
FROM stats_social_clicks AS sc
WHERE sc.social_network = 'facebook'
AND sc.campaign_id IN ('639ba3c9d86726f2ef5a6ca3','2bce996549ed7acb','f91491361140ccd81a7ab8bb','3d4d9a45bba4b8ef9c22edbc','VhFfwsAnxr9OBfRvGWKsyr7H','0819c9ff210c24f9efcb16fc')
AND sc.is_active = 1
) AS tblA
JOIN
(SELECT count(target_id) AS numTwitterClicks
FROM stats_social_clicks AS sc
WHERE sc.social_network = 'twitter'
AND sc.campaign_id IN ('639ba3c9d86726f2ef5a6ca3','2bce996549ed7acb','f91491361140ccd81a7ab8bb','3d4d9a45bba4b8ef9c22edbc','VhFfwsAnxr9OBfRvGWKsyr7H','0819c9ff210c24f9efcb16fc')
AND sc.is_active = 1
) AS tblB
) as tbl3
WHERE campaignID IN ('639ba3c9d86726f2ef5a6ca3','2bce996549ed7acb','f91491361140ccd81a7ab8bb','3d4d9a45bba4b8ef9c22edbc','VhFfwsAnxr9OBfRvGWKsyr7H','0819c9ff210c24f9efcb16fc')

SQL search Result, Group by ID number

I'm having some issues with trying to fix this SQL Query
This is a custom search query which is searching for the word 'weddings' on all pages on this CMS system.
At the moment I am getting the same page appear on the first 5 rows because the word 'weddings' appears 5 times. What I want to do is combine the rows with the same ID number into 1 row so it doesn't appear multiple times.
I thought doing a group by at the end of this statement would do this but I keep getting an SQL syntax error
GROUP BY `documents`.`id`
I have attached the full SQL bellow with an image of the output i currently get.... Any idea?
SELECT `documents`.*,
`documenttypes`.`name` as `doctype`,
`articles`.`id` as `article_id`,
`articles`.`language_id`,
`articles`.`title`,
`articles`.`template`,
`articles`.`slug`,
`articles`.`path`,
`articles`.`slug_title`,
MATCH ( elements.textvalue )AGAINST ( 'weddings' ) AS score,
elements.textvalue AS matching,
LOWER(`articles`.`title`)
LIKE '%weddings%' as 'like_title',
( MATCH ( elements.textvalue )
AGAINST ( 'weddings' ) ) + IF(( LOWER(`articles`.`title`)
LIKE '%weddings%'),1, 0) + IF((LOWER(`elements`.`textvalue`)
LIKE '%weddings%'),1, 0) as total FROM (`documents`)
LEFT JOIN `articles` ON `articles`.`document_id` = `documents`.`id`
LEFT JOIN `documenttypes` ON `documents`.`documenttype_id` = `documenttypes`.`id`
LEFT JOIN `documents_users` AS du ON `documents`.`id` = du.`document_id`
LEFT JOIN `documents_usergroups` AS dug ON `documents`.`id` = dug.`document_id`
LEFT JOIN elements ON `elements`.`article_id` = `articles`.`id`
WHERE `documents`.`trashed` = 0
AND `documents`.`published` = 1
AND `articles`.`status_id` = 1
AND `articles`.`language_id` = 1
AND (`documents`.`no_search` = '0'
OR `documents`.`no_search` IS NULL)
AND ( (dug.usergroup_id IS NULL)
AND (du.user_id IS NULL) )
AND (`documents`.`startdate` < NOW()
OR `documents`.`startdate` = '0000-00-00 00:00:00' OR `documents`.`startdate` IS NULL)
AND (`documents`.`enddate` > NOW()
OR `documents`.`enddate` = '0000-00-00 00:00:00'
OR `documents`.`enddate` IS NULL)
HAVING (total > 0)
ORDER BY label ASC,
total DESC LIMIT 0,10
You can try to use the statement DISTINCT:
SELECT DISTINCT 'documents'.*,
'documenttypes'.'name' as 'doctype',
'articles'.'id' as 'article_id',
...
GROUP BY lets you use aggregate functions, like AVG, MAX, MIN, SUM, and COUNT which apparently you don't use.

Is there any way to find the value of a query?

I recently made a system that ranks each players depending on their points. Well the way the system gets the points is rather confusing. After using this system for over 24 hours, I have found out that it is not organizing it according to the points. But then it suddenly occurred to me, that I could be calculating the points wrong in a way that does not represent the SQL query. Here is my SQL query that my rankings uses:
SELECT * , playeruid AS player_id, (
(
SELECT COALESCE(sum(player1points),0)
FROM `mybb_matches`
WHERE player1uid = player_id AND gid = $id AND timestamp < $time AND winneruid is NOT NULL AND dispute != 3 )
+
(
SELECT COALESCE(sum(player2points),0)
FROM `mybb_matches`
WHERE player2uid = player_id AND gid = $id AND timestamp < $time AND winneruid is NOT NULL AND dispute != 3 )
+
(
SELECT SUM( rank )
FROM `mybb_matchesgame`
WHERE playeruid = player_id AND gid = $id )
)
AS points
FROM mybb_matchesgame WHERE gid = $id
ORDER BY points DESC
Now that this is shown, I was wondering if there's any way to grab the value of "points" and display it somehow so I can verify the number. Is this possible?
There are no group by statements in the queries, so the SUM is most likely not over the expected set. Also COALESCE can be replaced with IFNULL, which might be a bit more efficient.
SELECT q.* , playeruid AS player_id, a.points+b.points+c.points AS points
FROM mybb_matchesgame q
LEFT JOIN (
SELECT IFNULL(SUM(player1points),0) as points,player_id
FROM `mybb_matches`
WHERE timestamp < $time AND winneruid is NOT NULL AND dispute != 3
GROUP BY player_id) a ON player1uid = a.player_id
LEFT JOIN (
SELECT IFNULL(sum(player2points),0) as points,player_id
FROM `mybb_matches`
WHERE timestamp < $time AND winneruid is NOT NULL AND dispute != 3
GROUP BY player_id) b ON player2uid = b.player_id
LEFT JOIN (
SELECT IFNULL(SUM( rank ),0) as points,player_id
FROM `mybb_matchesgame`
GROUP BY player_id) c ON playeruid = c.player_id
WHERE gid = $id
ORDER BY a.points+b.points+c.points DESC;

Select 2 random rows from a table from each category MySQL [duplicate]

I have a table with records and it has a row called category. I have inserted too many articles and I want to select only two articles from each category.
I tried to do something like this:
I created a view:
CREATE VIEW limitrows AS
SELECT * FROM tbl_artikujt ORDER BY articleid DESC LIMIT 2
Then I created this query:
SELECT *
FROM tbl_artikujt
WHERE
artikullid IN
(
SELECT artikullid
FROM limitrows
ORDER BY category DESC
)
ORDER BY category DESC;
But this is not working and is giving me only two records?
LIMIT only stops the number of results the statement returns. What you're looking for is generally called analytic/windowing/ranking functions - which MySQL doesn't support but you can emulate using variables:
SELECT x.*
FROM (SELECT t.*,
CASE
WHEN #category != t.category THEN #rownum := 1
ELSE #rownum := #rownum + 1
END AS rank,
#category := t.category AS var_category
FROM TBL_ARTIKUJT t
JOIN (SELECT #rownum := NULL, #category := '') r
ORDER BY t.category) x
WHERE x.rank <= 3
If you don't change SELECT x.*, the result set will include the rank and var_category values - you'll have to specify the columns you really want if this isn't the case.
SELECT * FROM (
SELECT VD.`cat_id` ,
#cat_count := IF( (#cat_id = VD.`cat_id`), #cat_count + 1, 1 ) AS 'DUMMY1',
#cat_id := VD.`cat_id` AS 'DUMMY2',
#cat_count AS 'CAT_COUNT'
FROM videos VD
INNER JOIN categories CT ON CT.`cat_id` = VD.`cat_id`
,(SELECT #cat_count :=1, #cat_id :=-1) AS CID
ORDER BY VD.`cat_id` ASC ) AS `CAT_DETAILS`
WHERE `CAT_COUNT` < 4
------- STEP FOLLOW ----------
1 . select * from ( 'FILTER_DATA_HERE' ) WHERE 'COLUMN_COUNT_CONDITION_HERE'
2. 'FILTER_DATA_HERE'
1. pass 2 variable #cat_count=1 and #cat_id = -1
2. If (#cat_id "match" column_cat_id value)
Then #cat_count = #cat_count + 1
ELSE #cat_count = 1
3. SET #cat_id = column_cat_id
3. 'COLUMN_COUNT_CONDITION_HERE'
1. count_column < count_number
4. ' EXTRA THING '
1. If you want to execute more than one statement inside " if stmt "
2. IF(condition, stmt1 , stmt2 )
1. stmt1 :- CONCAT(exp1, exp2, exp3)
2. stmt2 :- CONCAT(exp1, exp2, exp3)
3. Final "If" Stmt LIKE
1. IF ( condition , CONCAT(exp1, exp2, exp3) , CONCAT(exp1, exp2, exp3) )
share
Use group by instead of order by.

Returning Just count of records found in MYSQL query

I have the following MYSQL query which returns the number of photos found for each record where the number of photos is greater than 0.
SELECT advert_id, (SELECT COUNT( * ) FROM advert_images b WHERE b.advert_id = adverts.advert_id) AS num_photos
FROM adverts
WHERE adverts.approve = '1'
HAVING num_photos > 0
The query works fine, but I want to just return a count of the records found. i.e. the number of records which have at least one photo. I've tried to wrap the whole query in a COUNT, but it gives an error. I want to do this in the query, and not a separate count of records found in php.
SELECT COUNT(*) AS TotalRecords
FROM
(
SELECT a.advert_id, COUNT(*) AS num_photos
FROM adverts AS a
JOIN advert_images AS i
ON i.advert_id = a.advert_id
WHERE a.approve = '1'
GROUP BY a.advert_id
HAVING num_photos > 0
) AS mq
SELECT COUNT(*) FROM (SELECT advert_id, (SELECT COUNT( * ) FROM advert_images b WHERE b.advert_id = adverts.advert_id) AS num_photos
FROM adverts
WHERE adverts.approve = '1'
HAVING num_photos > 0) AS c
This should do the trick

Categories