Filter mysql results based on checkboxes - mysql

I am trying to filter mysql results based on checkboxes that have been ticked. My query works on the first check but returns nothing on the second filter. My checkbox array is $_POST['country'] which I implode in the GetSQLValueString function to create the comma separated values - (United Kingdom, France) etc. I am using the MySQL IN clause for the multiple selections.
I need it to filter multiple country selections
if (isset($_POST['country_submit']) && $_POST['country'] != '') {
mysql_select_db($database_tub, $tub);
$query_trade = sprintf("
SELECT u.user_id,
u.contact_person,
u.company,
u.country,
u.pic_small,
u.website,
SUM(u.trader_or_bond = %s
AND t.user_id IS NOT NULL) AS count
FROM users u
LEFT JOIN trading t ON u.user_id = t.user_id
WHERE u.trader_or_bond = %s AND u.country IN(%s)
GROUP BY u.user_id
ORDER BY COUNT(t.user_id) DESC",
GetSQLValueString('trader', "text"),
GetSQLValueString('trader', "text"),
GetSQLValueString(implode(',', $_POST['country']), "text"));
$trade = mysql_query($query_trade, $tub) or die(mysql_error());
}

I have come up with this but not sure if safe for MySQL injection plus its not as clean as I would like.
if (isset($_POST['country_submit']) && $_POST['country'] != '') {
$SingleQuotes = "'".implode("', '", array_map('mysql_real_escape_string', $_POST['country']))."'";
mysql_select_db($database_tub, $tub);
$query_trade = sprintf("
SELECT u.user_id,
u.contact_person,
u.company,
u.country,
u.pic_small,
u.website,
SUM(u.trader_or_bond = %s
AND t.user_id IS NOT NULL) AS count
FROM users u
LEFT JOIN trading t ON u.user_id = t.user_id
WHERE u.trader_or_bond = %s AND u.country IN($SingleQuotes)
GROUP BY u.user_id
ORDER BY COUNT(t.user_id) DESC",
GetSQLValueString('trader', "text"),
GetSQLValueString('trader', "text"));
$trade = mysql_query($query_trade, $tub) or die(mysql_error());
}

Related

How to view data based on user in codeigniter

I want to view data from mysql in codeigniter based on user who is logged in
but I got an error "A Database Error Occurred". I think I wrote the wrong code
t.USER = $this->session->userdata('user_id');
Here's the code:
function get_rekomen()
{
$query = $this->db->query("SELECT
c.*,
t.produk_id,
t.id_transdet,
t.kategori_id,
t.total_qty,
t.USER
FROM
transaksi_detail AS t
LEFT JOIN
(
SELECT
g.id_produk,
p.slug_produk,
p.foto,
p.foto_type,
p.harga_diskon,
p.diskon,
p.harga_normal,
p.judul_produk,
g.kat_id,
k.judul_kategori
FROM
(
SELECT
MAX(m.id_produk) AS id_produk,
m.kat_id
FROM
produk AS m
GROUP BY
m.kat_id
)
AS g
INNER JOIN
produk AS p
ON p.id_produk = g.id_produk
LEFT JOIN
kategori AS k
ON k.id_kategori = g.kat_id
)
AS c
ON c.kat_id = t.kategori_id
WHERE
t.USER = $ this -> session -> userdata('user_id');
<<// i think here's the problem
ORDER BY
total_qty DESC limit 1")->result();
return $query;
}
and the question is what is the correct code?
Here's one solution, but first make sure on your controller the $this->load->library('session'); is loaded or you can just add in on autoload.php.
Also you must add parameter to your model that will handle the user_id in session, so for example here's your model looks like:
function get_rekomen($user_id) { ...your query here... }
Then on condition using the user_id will be
t.USER = $user_id;
So on your controller, you can call your model like:
$user_id = $this->session->userdata('user_id');
$this->ModelClass->get_rekomen($user_id);
Additional: On your login phase, if the user success from logging in, the you must set the user data on session such as this $this->session->set_userdata('user_data', $session_data);
Hope this helps!
Maybe you can use this. You need to define $user_id first before adding them to WHERE statement...
$user_id = $this->session->userdata('user_id');
$sql = "SELECT c.*, t.produk_id, t.id_transdet, t.kategori_id, t.total_qty, t.USER
FROM transaksi_detail AS t
LEFT JOIN(SELECT g.id_produk, p.slug_produk, p.foto, p.foto_type, p.harga_diskon, p.diskon, p.harga_normal, p.judul_produk, g.kat_id, k.judul_kategori
FROM(SELECT MAX(m.id_produk) AS id_produk, m.kat_id
FROM produk AS m
GROUP BY m.kat_id)
AS g
INNER JOIN produk AS p ON p.id_produk = g.id_produk
LEFT JOIN kategori AS k ON k.id_kategori = g.kat_id)
AS c ON c.kat_id = t.kategori_id
WHERE t.USER = '$user_id'
ORDER BY total_qty DESC limit 1";
$query = $this->db->query($sql);
return $query->result();
Hope this can help you...

Select with case when + join, MYSQL

Guys are you able to help me in this below case?
I'm wanna to select and change the results:
My code looks as follow:
$USER_STORY = $this->lang->line('application_status_change_user_story');
$TO_DO = $this->lang->line('application_status_change_to_do');
$IN_PROGRESS = $this->lang->line('application_status_change_in_progress');
$DONE = $this->lang->line('application_status_change_done');
$UNDONE = $this->lang->line('application_status_change_undone');
SELECT sum(project_has_tasks.estimated_hours) as val, project_has_tasks.name,
project_has_tasks.start_date,
project_has_tasks.due_date,
project_has_tasks.progress,
TIME_FORMAT(SEC_TO_TIME(sum(project_has_tasks.time_spent)),'%k.%i')
as total_time, users.id, users.firstname, users.lastname,(case
when 'user_story' then '$USER_STORY'
when 'to_do' then '$TO_DO'
when 'in_progress' then '$IN_PROGRESS'
when 'done' then '$DONE'
when 'undone' then '$UNDONE'
else 'NOTHING'
end) as status
FROM project_has_tasks
RIGHT JOIN users ON project_has_tasks.user_id
= users.id WHERE project_has_tasks.project_id ='99'
GROUP BY project_has_tasks.id ASC
What to modify to get a proper results? Now I'm getting NOTHING in status column, but no errors.
I think your case statement is wrong, There no condition is checking so only it return the last else statement
SELECT sum(project_has_tasks.estimated_hours) as val, project_has_tasks.name,
project_has_tasks.start_date,
project_has_tasks.due_date,
project_has_tasks.progress,
TIME_FORMAT(SEC_TO_TIME(sum(project_has_tasks.time_spent)),'%k.%i')
as total_time, users.id, users.firstname, users.lastname,(case
when project_has_tasks.status = 'user_story' then '$USER_STORY'
when project_has_tasks.status = 'to_do' then '$TO_DO'
when project_has_tasks.status = 'in_progress' then '$IN_PROGRESS'
when project_has_tasks.status = 'done' then '$DONE'
when project_has_tasks.status = 'undone' then '$UNDONE'
else 'NOTHING'
end) as status
FROM project_has_tasks
RIGHT JOIN users ON project_has_tasks.user_id
= users.id WHERE project_has_tasks.project_id ='99'
GROUP BY project_has_tasks.id ASC

LEFT JOIN with exceptions

Here's my current query:
$q = "SELECT u.uid,CONCAT_WS(' ', u.first_name, u.last_name) name, CASE WHEN t.name IS NULL THEN 0 ELSE t.name END AS teamname ";
$q .= "FROM {$users} ";
$q .= "LEFT JOIN {$schedule} ON u.uid = s.uid ";
$q .= "LEFT JOIN {$products} ON p.admitting_id = u.uid ";
$q .= "LEFT JOIN {$teams} ON t.id = s.team ";
$q .= "WHERE (u.uid = {$current_user_id} AND u.roles = 'hoa') OR ";
$q .= "(p.id={$pid} AND p.admitting_id != 0) OR ";
$q .= "(t.admitting = 1 AND s.inactive != 1 AND s.role = 'hoa' AND (s.date = '{$today}' OR (s.date = '{$yesterday}' AND t.overnight = 1))) ";
$q .= "ORDER BY u.last_name,u.first_name,t.name";
What I need to get is:
Current User, if Current User has role hoa
User where uid matches admitting_id from products table
All users with role hoa who are scheduled today or were scheduled yesterday on an overnight shift. With those scheduled users, I need the names of the team they were/are scheduled with. Duplicate uids is good because I need all the different team names if they were scheduled on multiple teams.
What I don't need to get is:
Team name for options 1 and 2 above.
What I'm getting is:
Everything perfect for #3 above.
All possible team names for #1 and #2 above, whereas I want the team names to be 0 if they're not on the schedule.
I could split this up into three queries but that's not preferable.
Sometimes formatting the query out a bit helps visualise. It doesn't need to become three queries, I agree.
Can you provide some sample schema and data, ideally both in the question description and on something like sqlfiddle for us to play with?
It's hard to visualise your structure and data, but I'm speculating the issue is every record in users table is joining to schedule with the on clause you've used.
You could move the logic of condition 3 into the on clause (it's a left join, so nothing else will break) or duplicate it in the CASE statement in the SELECT:
$q = <<<SQL
SELECT
u.uid,
CONCAT_WS(' ', u.first_name, u.last_name) name,
IF(
WHEN t.name IS NULL THEN
0
ELSE
t.name
END AS teamname
FROM {$users} AS u
LEFT JOIN {$schedule} AS s ON (u.uid = s.uid)
LEFT JOIN {$products} AS p ON (p.admitting_id = u.uid)
LEFT JOIN {$teams} AS t ON
(
t.id = s.team AND
t.admitting = 1 AND
s.inactive != 1 AND
s.role = 'hoa' AND
(
s.date = '{$today}'
OR
(
s.date = '{$yesterday}' AND
t.overnight = 1
)
)
)
WHERE
( -- 1: Current User, if Current User has role hoa
u.uid = {$current_user_id} AND
u.roles = 'hoa'
)
OR
( -- 2: User where uid matches admitting_id from products table
p.id={$pid} AND
p.admitting_id != 0
)
OR
t.name IS NOT NULL
ORDER BY
u.last_name,
u.first_name,
t.name
SQL;
I'm absolutely not certain that'll fix your problem without something real to play with... Happy to continue looking if you can provide a working example sandpit.

Sorting by virtual key takes very long time in mysql

SELECT p . * , (
SELECT (
SELECT COUNT( * )
FROM sales s
WHERE s.affiliate != ''
AND s.pid = p.pid
AND s.saletype = 'sale' )
) AS popular
FROM products p
INNER JOIN members m ON m.uname = p.vendor
WHERE (m.mpid = p.pid OR p.marketavail = 'yes')
AND p.showinmarket = 'yes'
AND p.pname != ''
AND p.pdesc != ''
AND p.active = 'yes'
ORDER BY popular DESC
Here, If i use ORDER BY popular , it takes 17 seconds to load. without this ordering , query is executed in 4 seconds.
Please tell me why it is taking too much time while ordering by virtual columns?
All tables has index on required columns, so indexing is not the issue i guess. And if i run select count(*) for single product, it is executing in milliseconds.
And one more error i saw, If i remove SELECT word (second select word in my sql), it takes 105 sec to execute.
Please tell me if i need to give any more information.
Due to such delay in sorting, i am using php instead of mysql for sorting. Please help me to make it better.
Thank you in advance.
please try this query
SELECT p.column1,
p.column2,
p.column3,
COUNT(s.pid) as popular
FROM products p
INNER JOIN members m ON m.uname = p.vendor
LEFT JOIN sales s ON s.pid = p.pid AND s.affiliate != '' AND s.saletype = 'sale'
WHERE (m.mpid = p.pid OR p.marketavail = 'yes')
AND p.showinmarket = 'yes'
AND p.pname != ''
AND p.pdesc != ''
AND p.active = 'yes'
GROUP BY p.column1,p.column2,p.column3
ORDER BY popular DESC
column1,column2,column3 are just examples of columns you want, because you're select * I don't know what column names are from product. so change them to your actual column names.
edit: try this query see if it's any faster
SELECT p.pname, p.vendor, p.pid,
COUNT( s.pid ) AS popular
FROM products p INNER JOIN members m ON m.uname = p.vendor
LEFT JOIN
(SELECT pid FROM sales
WHERE affiliate != ''
AND saletype = 'sale'
)s
ON (s.pid = p.pid)
WHERE ( m.mpid = p.pid OR p.marketavail = 'yes' )
AND p.showinmarket = 'yes' AND p.pname != ''
AND p.pdesc != ''
AND p.active = 'yes'
GROUP BY p.pid, p.pname
ORDER BY popular DESC
if it runs faster you can pre-filter products too like this query and see if it runs even faster
SELECT p.pname, p.vendor, p.pid,
COUNT( s.pid ) AS popular
FROM (SELECT pname,vendor,pid,marketavail
FROM products
WHERE showinmarket = 'yes'
AND pname != ''
AND pdesc != ''
AND active = "yes"
)p
INNER JOIN members m ON m.uname = p.vendor
LEFT JOIN
(SELECT pid FROM sales
WHERE affiliate != ''
AND saletype = 'sale'
)s
ON (s.pid = p.pid)
WHERE ( m.mpid = p.pid OR p.marketavail = 'yes' )
GROUP BY p.pid, p.pname
ORDER BY popular DESC

Mysql Join for 3 tables

I have checked former posts and none has solved my problem yet, any help would be appreciated
MYSQL query to 3 tables (Users, Match, Interview)
Want to return the users name and interview # (if there is an interview number) for the specified Match.
But I do not want to limit the results to only users who have an interview. I tried JOIN, but cannot get it to work for 3 tables.
Here is what I have so far in PHP:
$query = "SELECT CONCAT(u.first_name,' ',u.last_name,'----',COALESCE(i.v_code,'')) as name, u.id as id
FROM #__users as u
JOIN #__bl_match as m ON ( (u.team_id = m.team1_id) OR
(u.team_id = m.team2_id) OR
(u.team_id = m.team3_id AND m.team3_id != 0) OR
(u.team_id = m.team4_id AND m.team4_id != 0) OR
(u.team_id = m.team5_id AND m.team5_id != 0) OR
(u.team_id = m.team6_id AND m.team6_id != 0) OR
(u.team_id = m.team7_id AND m.team7_id != 0) OR
(u.team_id = m.team8_id AND m.team8_id != 0) OR
(u.team_id = m.team9_id AND m.team9_id != 0) OR
(u.team_id = m.team10_id AND m.team10_id != 0))
AND m.id = ".$t_id."AND m.id != 0
JOIN #__bl_interview as i ON i.u_id = u.id";
$db->setQuery($query);
$parti12 = $db->loadObjectList();
If you want Users with no Interview, you'll need to use a LEFT JOIN to the interview table, but that means the interview number for that user will be NULL.
Since you're concatenating the number with the user name in your SELECT list, this results in the user's name being returned as NULL when they've got no interviews (since concatenating a string with a NULL value - or performing pretty much any other operation on a NULL value - produces a NULL result).
To avoid this, you must handle the case when i.v_code is NULL. The typical way to do that in MySQL is with the COALESCE function:
SELECT CONCAT(u.first_name, ' ', u.last_name, '----', COALESCE(i.v_code,'')) as name,
u.id as id
FROM #__users as u
JOIN #__bl_match as m ON ( (u.team_id = m.team1_id) OR
(u.team_id = m.team2_id) OR
(u.team_id = m.team3_id AND m.team3_id != 0) OR
(u.team_id = m.team4_id AND m.team4_id != 0) OR
(u.team_id = m.team5_id AND m.team5_id != 0) OR
(u.team_id = m.team6_id AND m.team6_id != 0) OR
(u.team_id = m.team7_id AND m.team7_id != 0) OR
(u.team_id = m.team8_id AND m.team8_id != 0) OR
(u.team_id = m.team9_id AND m.team9_id != 0) OR
(u.team_id = m.team10_id AND m.team10_id != 0))
AND m.id = ".$t_id."AND m.id != 0
LEFT JOIN #__bl_interview as i ON i.u_id = u.id"
Now, given the formatting you're applying to the name, you may be left with an extraneous ---- after the name with no subsequent interview code. If you'd like to avoid that, we can use IF instead of COALESCE to get a little smarter with our output, like so:
SELECT CONCAT(u.first_name, ' ', u.last_name, IF(i.v_code, '---- ' + i.v_code, '')) as name
Note what that's doing: if i.v_code is not NULL, the first expression in the IF evaluates to true, so the second expression is returned. Otherwise, the third expression (the empty string) is returned - so when i.v_code is NULL, you only output the user's name.