PHP MySQL Group By Using given array - php

************************************************
* id * location * status *
************************************************
* 1 * Shah Alam, Selangor * 1 *
* 2 * Seri Kembangan, Selangor * 1 *
************************************************
Hello guys, i have this kind of table in my database. Which in the location field, there is state. As you see, in the current field is Selangor.
How do i group it by Selangor and count it? I'm not sure whether using substr in mysql query is better or not. I do have an array which i think also possible to use to group and count.
$negeri = array('Selangor','Kedah','Johor','Negeri Sembilan','Perlis','Perak','Sarawak','Sabah','Kuala Lumpur','Kelantan','Terengganu','Melaka','Pahang','Pulau Pinang');
If i am about to use this array solution, how do i do it? Thanks

try this sql query,
select count(location) as locCount from state where location LIKE '%Selangor%' group by location;
in PHP
$sql = "select count(location) as locCount from state where location LIKE '%".$negeri[0]."%' group by location;";
Replace $negeri[0] with your variable name in php
EDIT: TO CREATE SQL QUERY IN LOOP TRY THIS CODE
as per #massquote's code, you can create a sql query in loop like below,
$negeri = array('Selangor','Kedah','Johor','Negeri Sembilan','Perlis','Perak','Sarawak','Sabah','Kuala Lumpur','Kelantan','Terengganu','Melaka','Pahang','Pulau Pinang');
$sql = "SELECT ";
$i=1;
$totCount = count($negeri);
foreach($negeri as $place){
$sql .= "SUM(CASE WHEN location LIKE '%".$place."%' THEN 1 ELSE 0 END) as place".$i;
if($i != $totCount) {
$sql .=", ";
}
$i++;
}
$sql .= " FROM state;";
echo $sql;
echo $sql will print the below sql query, you can use final $sql variable as sql query.
SELECT
SUM(CASE WHEN location LIKE '%Selangor%' THEN 1 ELSE 0 END) as place1,
SUM(CASE WHEN location LIKE '%Kedah%' THEN 1 ELSE 0 END) as place2,
SUM(CASE WHEN location LIKE '%Johor%' THEN 1 ELSE 0 END) as place3,
SUM(CASE WHEN location LIKE '%Negeri Sembilan%' THEN 1 ELSE 0 END) as place4,
SUM(CASE WHEN location LIKE '%Perlis%' THEN 1 ELSE 0 END) as place5,
SUM(CASE WHEN location LIKE '%Perak%' THEN 1 ELSE 0 END) as place6,
SUM(CASE WHEN location LIKE '%Sarawak%' THEN 1 ELSE 0 END) as place7,
SUM(CASE WHEN location LIKE '%Sabah%' THEN 1 ELSE 0 END) as place8,
SUM(CASE WHEN location LIKE '%Kuala Lumpur%' THEN 1 ELSE 0 END) as place9,
SUM(CASE WHEN location LIKE '%Kelantan%' THEN 1 ELSE 0 END) as place10,
SUM(CASE WHEN location LIKE '%Terengganu%' THEN 1 ELSE 0 END) as place11,
SUM(CASE WHEN location LIKE '%Melaka%' THEN 1 ELSE 0 END) as place12,
SUM(CASE WHEN location LIKE '%Pahang%' THEN 1 ELSE 0 END) as place13,
SUM(CASE WHEN location LIKE '%Pulau Pinang%' THEN 1 ELSE 0 END) as place14
FROM state;

You can do something like this.
SELECT 'Selangor' as state,
SUM(CASE WHEN location like '%, Selangor%' then 1 Else 0 end) AS cnt from yourtable
UNION ALL
SELECT 'Kedah' as state,
SUM(CASE WHEN location like '%, Kedah%' then 1 Else 0 end) AS cnt from yourtable;
Just generate the sql using loop in php then execute the script.

Related

Need help on priority search(sort by relevance) in PHP

So i picked up how to sort by priority but right now i'm having trouble with it.
My codes look like this :
$qry = "SELECT p.ProductID, p.ProductTitle, p.ProductImage, p.ProductDesc, p.Price, p.Quantity, p.Offered, p.OfferedPrice, p.OfferStartDate, p.OfferEndDate, NOW() AS 'Today'
,(case when p.ProductTitle LIKE '%$SearchText%' then 1 else 0 end) +
(case when p.ProductDesc LIKE '%$SearchText%' then 1 else 0 end) +
(case when cp.CategoryID = $catID then 1 else 0 end) +
(case when p.Offered = $productStatus AND p.OfferStartDate < NOW() AND p.OfferEndDate > NOW() then 1 else 0 end) +
(case when p.Offered = $productStatus AND p.OfferStartDate IS NULL AND p.OfferedPrice IS NULL then 1 else 0 end) +
(case when p.Price > $priceMin AND p.Price < $priceMax then 1 else 0 end) +
(case when p.OfferedPrice > $priceMin AND p.OfferedPrice < $priceMax then 1 else 0 end) as priority
FROM Product p INNER JOIN CatProduct cp ON p.ProductID = cp.ProductID
WHERE p.ProductTitle LIKE '%$SearchText%' OR p.ProductDesc LIKE '%$SearchText%' OR cp.CategoryID = $catID
OR ( (p.Price > $priceMin) AND (p.Price < $priceMax) ) OR ( (p.OfferedPrice > $priceMin) AND (p.OfferedPrice < $priceMax) ) ";
if($productStatus == '0')
{
$qry .= "AND p.Offered = $productStatus AND p.OfferStartDate IS NULL AND p.OfferedPrice IS NULL";
}
else if($productStatus == '1')
{
$qry .=" AND p.Offered =$productStatus AND p.OfferStartDate < NOW() AND p.OfferEndDate > NOW() ";
}
$qry .= " ORDER BY priority desc";
What i'm trying to accomplish here is to make a search function that would prioritize and display as the top few results based on relevance. Right now i'm having trouble sorting by the product status (on offer or not on offer). The "on offer" one works but i cant seem to get "not on offer" to work.
To determine a product to be on offer or not on offer, there is a p.Offered = 0 (not on offer) or p.Offered = 1 (on offer). But we also have a offer period so even if the product is suppose to be on offer, it still has to be within the offer period.
Any ideas how i can get it to work? I still want to keep it to display it and sort it based on relevance

MySQL alias calculation

It confuses me.. total left calculation seems doesn't work.
I am trying to get the total voucher and get total used and the total left.
please help.
SELECT
(IFNULL(SUM(value), 0)) AS total_voucher,
(
SELECT
IFNULL(SUM(value), 0))
FROM
voucher_history
WHERE
idUser = 1 AND isUsed = 1 AND DATE(FROM_UNIXTIME(datetime)) = '2014-03-04'
) AS total_used,
(total_voucher-total_used) AS total_left
FROM
voucher_history
WHERE
idUser = 1 AND isUsed = 0 AND DATE(FROM_UNIXTIME(datetime)) <= '2014-03-05'
You can do this with conditional aggregation, rather than using a subquery:
SELECT coalesce(SUM(value), 0)) AS total_voucher,
sum(case when is_used = 1 then value else 0 end) as total_used,
sum(case when is_used = 1 then 0 else value end) as total_left
FROM voucher_history
WHERE idUser = 1 AND DATE(FROM_UNIXTIME(datetime)) <= '2014-03-05';
Your query has the problem that it is trying to use column aliases (total_voucher and total_used) in the same select statement. SQL does not support this. You would need to use a subquery to get that functionality.

MySQL pivot with multiple counts

This is a snapshot of my MySQL table:
Is it possible to write a query to get such a pivot table like output...
How about something like
SELECT url_host,
SUM(CASE WHEN post_id = -1 THEN 1 ELSE 0 END) as post_id_minus1,
SUM(CASE WHEN post_id = 0 THEN 1 ELSE 0 END) as post_id_0,
etc...
FROM YOUR_TABLE
GROUP BY url_host
You can use CASE statement on this to pivot your table.
SELECT url_host,
COUNT(CASE WHEN post_ID = -1 THEN 1 ELSE NULL END) Negative_One,
COUNT(CASE WHEN post_ID = 0 THEN 1 ELSE NULL END) Zero,
COUNT(CASE WHEN post_ID > 0 THEN 1 ELSE NULL END) Greater_Zero
FROM tableName
GROUP BY url_host
SQLFiddle Demo

Group sql query

I want to have an only query with 2 queries but i don't know how to start...
My queries count the positive/negative votes for a comment.
SELECT COUNT(id) AS votes_no FROM comments_votes WHERE vote = 0 AND id_comment = 1
SELECT COUNT(id) AS votes_no FROM comments_votes WHERE vote = 1 AND id_comment = 1
I set vars to put negative and positives votes : $votes_no and $votes_yes
Then i have a final var : $votes_calc = $votes_yes - $votes_no;
How can i get the number of votes_yes, votes_no and votes_calc in only one query?
Thanks a lot!
select votes_no, votes_yes, votes_yes-votes_no as votes_calc
from (select sum(case when vote = 0 then 1 else 0 end) as votes_no,
sum(case when vote = 1 then 1 else 0 end) as votes_yes
from comments_votes
where id_comment = 1) a
select vote,count(id)
from Comment_votes
group by vote
WHERE id_comment = 1
with rollup
The with Rollup will add a row with a NULL value in the vote column and the total in the second column
I merge the query getting the comments and the comments votes and it seems to work :)
SELECT a.*, nb_votes, votes_yes-votes_no AS votes_calc
FROM comments AS a
LEFT JOIN (
SELECT id_comment, COUNT(id) AS nb_votes,
SUM(CASE WHEN vote = 0 THEN 1 ELSE 0 END) AS votes_no,
SUM(CASE WHEN vote = 1 THEN 1 ELSE 0 END) AS votes_yes
FROM comments_votes GROUP BY id_comment
) AS c ON (a.id = c.id_comment)
WHERE a.status = 'approved' AND a.id_post = 1 ORDER BY a.time ASC
Thanks for your answers :)

do i have to specify the database name in select statement while hosting?

i am getting an error while querying this select statement.
$comments = dbgetvar("SELECT SUM(CASE WHEN c.approve = '1' AND c.spam = '0' THEN 1 ELSE 0 END) AS approved,
SUM(CASE WHEN c.approve = '0' AND c.spam = '0' THEN 1 ELSE 0 END) AS pending,
SUM(CASE WHEN c.spam = '1' THEN 1 ELSE 0 END) AS spam,
COUNT(*) AS count
FROM COMMENTS c");
the above code works fine on my local machine using WAMP server. but when i host it in my server powered by cpanel it gives the following error.
Notice: dbget: Table
'bhatkaln_test.COMMENTS' doesn't exist
in SELECT SUM(CASE WHEN c.approve =
'1' AND c.spam = '0' THEN 1 ELSE 0
END) AS approved, SUM(CASE WHEN
c.approve = '0' AND c.spam = '0' THEN
1 ELSE 0 END) AS pending, SUM(CASE
WHEN c.spam = '1' THEN 1 ELSE 0 END)
AS spam, COUNT(*) AS count FROM
COMMENTS c in
/home/bhatkaln/public_html/test/admin-login/models/validation.php
on line 154
what does the above error mean? in the database the comments table do exist.
You are testing your server on Windows, where the table names are not case sensitive, since they ultimately refer to files.
When you upload to your Linux based server, the file system there is case sensitive. It doesn't work because you specify COMMENTS but the table name, presumably, is comments.
See Identifier Case Sensitivity in the MySQL manual for more information.

Categories