Wordpress custom wp_users, wp_usermeta join not ordering properly - mysql

I have a custom query to pull users with their user_meta for a statistics plugin I wrote. I am able to select (WHERE) based on a date range, as well as ORDER BY any of the meta fields, however, I cannot do both at the same time. I am losing my mind!! Here is my query (with default variables for reference underneath) ...
$getUserData = $wpdb->get_results("SELECT
ID, user_email, user_registered,
first_name.meta_value as first_name,
last_name.meta_value as last_name,
telephone.meta_value as telephone,
country.meta_value as country,
company.meta_value as company,
address.meta_value as address,
city.meta_value as city,
professional_title.meta_value as professional_title,
state.meta_value as state,
areas_of_interest.meta_value as areas_of_interest
FROM wp_users
LEFT JOIN wp_usermeta AS first_name ON first_name.user_id=ID
AND first_name.meta_key='first_name'
LEFT JOIN wp_usermeta AS last_name ON last_name.user_id=ID
AND last_name.meta_key='last_name'
LEFT JOIN wp_usermeta AS telephone ON telephone.user_id=ID
AND telephone.meta_key='telephone'
LEFT JOIN wp_usermeta AS country ON country.user_id=ID
AND country.meta_key='country'
LEFT JOIN wp_usermeta AS company ON company.user_id=ID
AND company.meta_key='company'
LEFT JOIN wp_usermeta AS address ON address.user_id=ID
AND address.meta_key='address'
LEFT JOIN wp_usermeta AS city ON city.user_id=ID
AND city.meta_key='city'
LEFT JOIN wp_usermeta AS professional_title ON professional_title.user_id=ID
AND professional_title.meta_key='professional_title'
LEFT JOIN wp_usermeta AS state ON state.user_id=ID
AND state.meta_key='state'
LEFT JOIN wp_usermeta AS areas_of_interest ON areas_of_interest.user_id=ID
AND areas_of_interest.meta_key='areas_of_interest'
" . $where . "
ORDER BY " . $orderBy . " " . $sortOrder . " LIMIT 0, " . $page_limit);
$where = "WHERE (user_registered >= '" . $_REQUEST['from'] . " 00:00:00' and user_registered <= '" . $_REQUEST['to'] . " 00:00:00') ";
$orderBy = "user_registered";
$sortOrder = "ASC";

hint - mysql_error() telling us that if you place your variables correct you still forgeting to set there $page_limit

Related

Concatenated column to be store in two different columns

I have a website and when customer register on it the data is stored in the admin panel, Now If you see in the below code at the first line emp_name and emp_ID is saving in a single column, and I want to save it in two different columns how to differentiate it.
$sql = "SELECT c.customer_id, CONCAT(c.emp_name, ' ', c.emp_ID) AS name,
c.email, c.mobile_no, CONCAT(oca.address_1,oca.address_2) AS address,
oca.city, oca.postcode, occ.name as Country, c.ip,
IF( c.status = 1, 'Enabled','Disabled' ) AS status,
IF( c.approved = 1, 'Yes', 'No' ) AS approved, c.date_added, cgd.name AS customer_group FROM " . DB_PREFIX . "customer c
LEFT JOIN " . DB_PREFIX . "customer_group_description cgd ON (c.customer_group_id = cgd.customer_group_id)
LEFT JOIN " . DB_PREFIX . "address oca ON (c.address_id=oca.address_id)
LEFT JOIN " . DB_PREFIX . "country occ ON (oca.country_id=occ.country_id)
WHERE cgd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
Try this:
SELECT c.customer_id,
c.emp_id,
c.emp_name AS NAME,
c.email,
c.mobile_no,
Concat(oca.address_1,oca.address_2) AS address,
oca.city,
oca.postcode,
occ.NAME AS Country,
c.ip,IF( c.status = 1, 'Enabled', 'Disabled' ) as status,
IF( c.approved = 1, 'Yes', 'No' ) AS approved, c.date_added, cgd.NAME AS customer_group FROM " . DB_PREFIX . "customer c LEFT JOIN " . DB_PREFIX . "customer_group_description cgd ON (
c.customer_group_id = cgd.customer_group_id
)
LEFT JOIN " . DB_PREFIX . "address oca ON (
c.address_id=oca.address_id
)
LEFT JOIN " . DB_PREFIX . "country occ ON (
oca.country_id=occ.country_id
)
WHERE cgd.language_id = '" . (int)$this->config->get('config_language_id') . "'
MySQL CONCAT() function is used to concatenate two or more strings to form a single string. This is why you see the data in a single column. Simply remove the function, if you want to show the data in separate columns.

Combining 3 querys on SQL

I have a table with both, Products and Sevices. And I store the products brands, product names and services names on separate tables.
I get the list of Services with this Query:
SELECT maeinvs.idInv, CONCAT(services.Service, " ", maeinvs.Detail) AS Name
FROM maeinvs
INNER JOIN services
ON services.idService = maeinvs.idService
And the list of Products with this one:
SELECT maeinvs.idInv, CONCAT(brands.Brand, " ", products.Product, " ", maeinvs.Detail) AS Name
FROM maeinvs
INNER JOIN products
ON products.idProduct = maeinvs.idProduct
INNER JOIN brands
ON brands.idBrand = maeinvs.idBrand
I need to get a Query like this, but instead of the idInv field I need the actual Name of the Product or Service. Any ideas?
SELECT idInv, Desc, Qnty, Price
FROM invoicedetails
WHERE idInvoice = $id
Thanks.
SELECT maeinvs.idInv, CONCAT(services.Service, " ", maeinvs.Detail) AS Name,
"" AS Desc, 0 AS Qnty, 0 AS Price
FROM maeinvs
INNER JOIN services
ON services.idService = maeinvs.idService
UNION
SELECT maeinvs.idInv, CONCAT(brands.Brand, " ", products.Product, " ", maeinvs.Detail) AS Name,
"" AS Desc, 0 AS Qnty, 0 AS Price
FROM maeinvs
INNER JOIN products
ON products.idProduct = maeinvs.idProduct
INNER JOIN brands
ON brands.idBrand = maeinvs.idBrand
UNION
SELECT idInv,
"" AS Name,
Desc, Qnty, Price
FROM invoicedetails
WHERE idInvoice = $id
I've written what I've changed on next line
As the columns match each other, UNION will work.
I still don't know how to do it on a single query (I just know the basics; an Alias?) but solved it doing a VIEW and then a JOIN with my invoicedetails table.
VIEW:
SELECT maeinvs.idInv, CONCAT(services.Service, " ", maeinvs.Detail) AS Name
FROM maeinvs
INNER JOIN services
ON services.idService = maeinvs.idService
UNION
SELECT maeinvs.idInv, CONCAT(brands.Brand, " ", products.Product, " ", maeinvs.Detail) AS Name
FROM maeinvs
INNER JOIN products
ON products.idProduct = maeinvs.idProduct
INNER JOIN brands
ON brands.idBrand = maeinvs.idBrand
QUERY:
SELECT viewnames.Name, invoicedetails.Desc, invoicedetails.Qnty, invoicedetails.Price
FROM invoicedetails
INNER JOIN viewnames ON viewnames.idInv = invoicedetails.idInv
WHERE invoicedetails = $id

My sql search syntax implementation

How can I implement search function:
where sub_menu_name like '%".$kws."%'
into my working one:
SELECT DISTINCT p.id, p.sub_menu_id, p.sub_menu_name, m.image_id, i.file_url, m.default_menu_id, p.restaurant_id, p.status, p.sub_menu_price
FROM sub_sub_menu AS p
INNER JOIN menu AS m ON m.default_menu_id = p.sub_menu_id
OR m.id = p.sub_menu_id
INNER JOIN icon AS i ON i.id = m.image_id
WHERE p.restaurant_id = '" . (int) $_SESSION['uid'] . "' "
Thanks for any help!
SELECT DISTINCT p.id, p.sub_menu_id, p.sub_menu_name, m.image_id, i.file_url, m.default_menu_id, p.restaurant_id, p.status, p.sub_menu_price
FROM sub_sub_menu AS p
INNER JOIN menu AS m ON m.default_menu_id = p.sub_menu_id
OR m.id = p.sub_menu_id
INNER JOIN icon AS i ON i.id = m.image_id
WHERE p.restaurant_id = '" . (int) $_SESSION['uid'] . "'
AND sub_menu_name LIKE '%".$kws."%'
I think this is what you want.
But I wonder why you have ". and ." before and after $kws. It's meant for concatenation so it won't work in SQL. If you want to check for $kws IN a value, the % % are enough.

select items from story where story.uid equal to uid or story.uid equal to friend.uid or friend.fid and accepted

How could I fetch a specific record only and if a condition is met?
I have the code as
"SELECT a.id, a.text, a.uid, a.time
FROM story a INNER JOIN friends b
ON ((a.uid = '" . $uid . "') OR
(b.uid = '" . $uid . "' AND accepted='1') OR
(b.fid = '" . $uid . "' AND accepted='1'))
ORDER BY a.time DESC
LIMIT 3";
It works fine except that when the friends table is empty, it will not show the story records.
what i want to achieve is
if the uid in table story is equal to logged in uid (user), then show the text from table story (meaning it is his own story)
if the uid in table story is equal to uid in table friends and its friendship is accepted OR if the uid in table story is equal to fid in table friends and its friendship is accepted then show the text in table story (meaning the story is from a friend and its shown only if friendship is accepted)
if there is no friendships at all, just show own stories from table story and omit others
I think you are not using proper join format. It should be as :
SELECT field_name
FROM table1 t1
INNER JOIN table2 t2
ON t1.id = t2.some_id
WHERE..
You can check the basics here.
In your case you should write query as following:
"SELECT a.id, a.text, a.uid, a.time
FROM story a INNER JOIN friends b
ON a.id = b.some_id WHERE ((a.uid = '" . $uid . "') OR
(b.uid = '" . $uid . "' AND accepted='1') OR
(b.fid = '" . $uid . "' AND accepted='1'))
ORDER BY a.time DESC
LIMIT 3";
I think it will help.

SUM() on all rows of a LEFT JOIN?

I've been playing with LEFT JOINs and I'm wondering if it's possible to get the SUM of all the ratings so far from all users in the below query. The below get's me the information on if the logged in user has rated or not, but i want to show total ratings from other users also.
$query = mysql_query("
SELECT com.comment, com.comment_id, r.rate_up, r.rate_down
FROM comments com
LEFT JOIN ratings r
ON com.comment_id = r.comment_id
AND r.user_id = '" . $user_id_var . "'
WHERE page_id = '" . $category_id_var. "'");
I've tried the following but i only get one comment/row returned for some reason.
$query = mysql_query("
SELECT com.comment, com.comment_id,
r.rate_up, r.rate_down
SUM(r.rate_up) AS total_up_ratings,
SUM(r.rate_down) AS total_down_ratings,
FROM comments com
LEFT JOIN ratings r
ON com.comment_id = r.comment_id
AND r.user_id = '" . $user_id_var . "'
WHERE page_id = '" . $category_id_var. "'");
Any help appreciated. Do i need a different kind of JOIN?
Have you tried using GROUP BY page_id on the end of your SQL?
You could do it something like this:
SELECT
com.comment,
com.comment_id,
Total.total_down_ratings,
Total.total_up_ratings
FROM comments com
LEFT JOIN
(
SELECT
SUM(r.rate_up) AS total_up_ratings,
SUM(r.rate_down) AS total_down_ratings,
r.comment_id
FROM
ratings r
GROUP BY
r.comment_id
) AS Total
ON com.comment_id = Total.comment_id
AND r.user_id = '" . $user_id_var . "'
WHERE page_id = '" . $category_id_var. "'"
If you use an aggregation function in SQL (like SUM()) you will need a corresponding GROUP BY clause.
In your case the most likely one would be com.comment_id; this will give you the sum of all ratings per comment_id:
I don't know if you are duplicating comment rows for purpose but if not you can try write subselect for ratings like this:
select comment_id, user_id, sum(rate_up) as sum_rate_up,
sum(rate_down) as sum_rate_down from ratings
group_by comment_id, user_id;
and then include it in your join query:
select com.comment, com.comment_id, r.user_id, r.sum_rate_up,
r.sum_rate_down from comments com
left join (select comment_id, user_id, sum(rate_up) as sum_rate_up,
sum(rate_down) as sum_rate_down from ratings
group_by comment_id, user_id) as r
on com.comment_id = r.comment_id where page_id = '".$category_id_var."'