I am trying to write a long tail where statement which containing another select query and how I can do it. Currently, I am using Ignited Datatables Library with my CodeIgniter 3 installation.
SELECT ContactId,
ReceiverId,
SenderId,
IF(ReceiverId = 1,
(SELECT first_name
FROM users
WHERE users.id = contacts_connectivity.SenderId),
(SELECT first_name
FROM users
WHERE users.id = contacts_connectivity.ReceiverId)) AS FirstName,
IF(ReceiverId = 1,
(SELECT email
FROM users
WHERE users.id = contacts_connectivity.SenderId),
(SELECT email
FROM users
WHERE users.id = contacts_connectivity.ReceiverId)) AS SenderEmail,
IF(ReceiverId = 1,
(SELECT phone
FROM users
WHERE users.id = contacts_connectivity.SenderId),
(SELECT phone
FROM users
WHERE users.id = contacts_connectivity.ReceiverId)) AS SenderPhone,
IF(ReceiverId = 1,
(SELECT company
FROM users
WHERE users.id = contacts_connectivity.SenderId),
(SELECT company
FROM users
WHERE users.id = contacts_connectivity.ReceiverId)) AS SenderCompany,
ModulesId,
(SELECT ModuleName
FROM modules
WHERE ModuleId = contacts_connectivity.ModulesId) AS ModuledName,
FROM_UNIXTIME(AddedDate, "%m/%d/%Y") AddedDate
FROM contacts_connectivity
WHERE (ReceiverId = 1
OR SenderId = 1)
AND (ReceiverId
OR SenderId NOT IN
(SELECT (ReceiverId
OR SenderId)
FROM contacts_connectivity
WHERE (ReceiverId
OR SenderId) = 1))
I noticed that My query doesn't return any array at all. I already tried to write the where statement like this-
$this->datatables->where("(ReceiverId = ' . $id . ' OR SenderId = ' . $id . ')");
$this->datatables->where(" AND (ReceiverId OR SenderId NOT IN (SELECT (ReceiverId OR SenderId) FROM contacts_connectivity WHERE (ReceiverId OR SenderId) = ' . $id . '");
What am I doing wrong?
You invalid use parameters. Try something like this:
$this->datatables->where("(ReceiverId=$id OR SenderId=$id )");
Second string should be fixed too the same way. Also check that your $id param properly escaped.
Related
How can I modify this query to get the attachment url link to my custom post type.
I have tried several solution from the web but none of them are giving the expected result.
$results = $wpdb->get_results(
"SELECT ID, post_title, {$wpdb->prefix}terms.name, GROUP_CONCAT(meta_value SEPARATOR ', ') AS pictoInfos
FROM {$wpdb->prefix}posts
INNER JOIN {$wpdb->prefix}term_relationships
ON ID = {$wpdb->prefix}term_relationships.object_id
INNER JOIN {$wpdb->prefix}terms
ON {$wpdb->prefix}term_relationships.term_taxonomy_id = {$wpdb->prefix}terms.term_id
INNER JOIN {$wpdb->prefix}postmeta
ON ID = {$wpdb->prefix}postmeta.post_id
WHERE (post_type = 'recette' AND post_status = 'publish')
AND (term_taxonomy_id = {$_GET['data']['id']} AND meta_key IN ( 'kilocalorie', 'difficulte', 'nombre_de_minutes' ) )
GROUP BY ID ORDER BY ID DESC ",
ARRAY_A );
I'm trying to make an Sql , that get all data from first table "posts_main" and then get the count of comments from second table "posts_comments"
I tried:
$sql = "SELECT * FROM posts_main, count(posts_comments.groupid)
INNER JOIN posts_comments ON posts_comments.groupid = posts_main.id
WHERE posts_main.user_id = '$user_id'
GROUP BY posts_main.id";
Please, how can i do that ?
thanks....
Try with below query.
$sql = "select posts_main.*,
(select groupid from posts_comments where groupid = posts_main.id group by groupid ) as count_group
from posts_main
WHERE posts_main.user_id = '$user_id' ";
Try this with subquery
SELECT posts.*,cnt FROM posts_main
INNER JOIN (select posts_comments.groupid,count(posts_comments.groupid) as cnt
group by posts_comments.groupid)a
ON a.groupid = posts_main.id
WHERE posts_main.user_id = '$user_id'
Here is my query:
SELECT *
FROM messages
WHERE status = 1
AND (
poster IN (SELECT thing FROM follows WHERE follower = :uid AND type = 3)
OR
topic_id IN (SELECT thing FROM follows WHERE follower = :uid AND type = 1)
)
ORDER BY post_date DESC LIMIT 0, 20
I want to know which clause the rows come from. From the poster IN (...) part or the topic_id IN (...) part? How can I do that?
A straightforward way:
SELECT *
, CASE WHEN poster IN (SELECT thing FROM follows WHERE follower = :uid AND type = 3) THEN 'poster'
ELSE 'topic_id' END AS from_clause
FROM messages <..>
Another way :
SELECT m.*
, CASE WHEN t1.thing IS NULL THEN 'topic_id' ELSE `poster` END AS from_clause
FROM messages m
LEFT JOIN (SELECT thing FROM follows WHERE follower = :uid AND type = 3) t1 ON m.poster = t1.thing
LEFT JOIN (SELECT thing FROM follows WHERE follower = :uid AND type = 1) t2 ON m.topic_id = t2.thing
WHERE m.status = 1 AND (t1.thing IS NOT NULL OR t2.thing IS NOT NULL)
Is there a way to join multiple count(*) queries to a single one? I know that i don't need to prepare the last two queries two times but that's not what the question is about. I have no idea how to do this in a correct way.
$sth = $this->_db->prepare('SELECT count(*) FROM posts WHERE topicid = ?');
$sth->execute( array( $this->_id ) );
$numPosts = $sth->fetch(\PDO::FETCH_ASSOC);
$sth = $this->_db->prepare('SELECT count(*) FROM topic_activity WHERE topicid = ?');
$sth->execute( array( $this->_id ) );
$numViews = $sth->fetch(\PDO::FETCH_ASSOC);
$sth = $this->_db->prepare('SELECT count(*) FROM topic_activity WHERE topicid = ? AND likes = 1');
$sth->execute( array( $this->_id ) );
$numLikes = $sth->fetch(\PDO::FETCH_ASSOC);
$sth = $this->_db->prepare('SELECT count(*) FROM topic_activity WHERE topicid = ? AND likes = -1');
$sth->execute( array( $this->_id ) );
$numDislikes = $sth->fetch(\PDO::FETCH_ASSOC);
SELECT count_post, topic_activity
FROM(
SELECT count(*) AS count_post, NULL AS topic_activity FROM posts WHERE topicid = ?
UNION
SELECT NULL AS count_post, count(*) AS topic_activity FROM topic_activity WHERE topicic =?
) T
GROUP by count_post, topic_activity
let me know if it works
Although the answer of user3106988 'works', I would have gone for a more 'vertical' approach (and also store the id in a variable so you only need to pass it once, could be this doesn't work in your environment though, so could be you'll need to replace the #id's with 4 question marks, but hopefully not) :
SET #id = ?;
SELECT info = 'Posts', count(*) FROM posts WHERE topicid = #id
UNION ALL
SELECT info = 'Views', count(*) FROM topic_activity WHERE topicid = #id
UNION ALL
SELECT info = 'Likes', count(*) FROM topic_activity WHERE topicid = #id AND likes = 1
UNION ALL
SELECT info = 'DisLikes', count(*) FROM topic_activity WHERE topicid = #id AND likes = -1
But that returns 4 records where you'll then need to extract the data out by means of the info field. So, building on the idea of user3106988's answer to return just 1 record with all the info in different fields you could actually go for the likes & disklikes in as little effort as below. Should be quite fast.
SET #id = ?;
SELECT SUM(count_posts) as count_posts,
SUM(views) as views,
SUM(likes) as likes,
SUM(dislikes) as dislikes
FROM(
SELECT COUNT(*) as count_posts,
0 as views,
0 as likes,
0 as dislikes
FROM posts
WHERE topicid = #id
UNION ALL
SELECT 0 as count_posts,
COUNT(*) as views,
SUM(Case WHEN likes = 1 THEN 1 ELSE 0 END) as likes,
SUM(Case WHEN likes = -1 THEN 1 ELSE 0 END) as dislikes
FROM topic_activity
WHERE topicid = #id
) T;
I'm having a problem trying to count the number of user records according to the user's id, however I'm using a subquery to join 2 tables that one has a count parameter but I get an error saying duplicate column name 'user_id.
The query:
$sql = "SELECT loc.location_id,
COUNT(loc.location_id) AS total_records
FROM locations loc
LEFT JOIN
(
SELECT usr.*,
loc.*
FROM
(
members usr
INNER JOIN locations loc
)
WHERE usr.user_id = " . $user_id . "
AND usr.account_disabled = 0
ORDER BY loc.submit_date DESC
) usr ON (loc.user_id = usr.user_id)";
All I need it is to return the user's info and the total_records count done by the COUNT function.
Cheers.
EDIT:
This is what I get returned for this SQL:
SELECT loc.location_id,
loc.street_name,
loc.city,
loc.state,
loc.county,
loc.country,
usr.user_id,
usr.username,
COUNT(loc.location_id) AS total_records
FROM locations loc
INNER JOIN members usr ON (loc.user_id = usr.user_id)
WHERE loc.user_id = $user_id
AND usr.account_disabled = 0
GROUP BY loc.location_id
It's not exactly clear why you've got the derived resultset or the LEFT JOIN. Try this:
SELECT loc.location_id,
COUNT(loc.location_id) AS total_records
FROM LOCATIONS_TABLE loc
INNER JOIN MEMBERS_TABLE usr
ON (loc.user_id = usr.user_id)
WHERE loc.user_id = $user_id
AND usr.account_disabled = 0
GROUP BY loc.location_id
I think the problem is this part:
SELECT usr.*,
loc.*
Both tables have a user_id