How to use if else condition with Join in php - php

I want to fetch questions of $id(dynamic,passing as parameter) and want to whether this is
"ParentbusinessId" or "businessId"
table name "nps_ques"
id config_id question
1 1 Lorem Ipsum
2 1 Lorem Ipsum2
3 1 Lorem Ipsum3
Table "nps_config"
id parentBusinessId businessId
1 4580 NULL
2 0 2
3 4580 3
I tried with following code
$this->db->select('nq.id as ques_id,nq.config_id as formId,nq.question,nc.parentBusinessId,nc.businessId)
->from('nps_ques nq')
->join("nps_config nc", "nc.id=nq.config_id")
->where("nq.config_id", $id)
->order_by("nq.id", "ASC");

You can use CASE.
See example below:
SELECT
config.id AS config_id,
questions.question,
case when config.parent_business_id is not null then config.parent_business_id else config.business_id end as business
FROM
questions
JOIN
config ON questions.config_id = config.id
WHERE
config.id = 1;

Related

MySQL get earliest row by type and status where type order is from array

i want to get earlest row that has status 0 but for type column is sorted by array, for example, I have array like below
$myArray = ['checkerA', 'detailMaker', 'checkerB', 'checkerD', 'checkerC']
And then I have table look like below. as you can see the order of data in the column type is 'CheckerC' first and then 'checkerD', but I want to get row based on my Array
id
name
type
status
5
sit
checkerD
0
4
Dolor
checkerC
0
3
Ipsum
checkerB
1
2
Lorem
detailMaker
1
1
John doe
checkerA
1
Here's my query that I have made. (btw I only want to get the id data)
SELECT MIN(CASE WHEN status = 0 THEN id END) FROM myTable
If I use that code, I'll get CheckerC, which is where my expectation is I want to get CheckereD.id
Is there any way that I can implement my array into the query? Thanks
You can use this query to get the row with status 0 and get the earliest entry
SELECT * FROM myTable where status =0 order by id asc LIMIT 1 OFFSET 0

mysqlCount not working with join,Showing wrong result

I have two tables"shopinfo" and "rating" and i am trying to count review with Join but showing me wrong result
Here is my first table "shopInfo"
id shopOpen shopname
1 2 abc
2 1 xyz
3 2 dnu
4 2 rfy
Here is my table "rating"
id shopId rating review
1 2 3 Lorem Ipsum
2 2 4 Lorem Ipsum
3 4 5 Lorem Ipsum
4 2 1 Lorem Ipsum
And here is my code which showing me wrong result in review count (showing me 6 , should be 3),
Where i am wrong ?
SELECT si.shopOpen, COUNT(r.review) as reviewCount, AVG(r.rating) AS AvgRating
FROM shopInfo si
LEFT JOIN rating r ON r.shopId=si.id
WHERE si.shopId = '2'
you are missing group by. when you use aggregated functions like sum(), avg() you have to group by non-aggregated column. In your case it is si.shopOpen
Here is the fiddle link provided by #VBoka
SELECT
si.shopOpen,
COUNT(r.review) as reviewCount,
AVG(r.rating) AS AvgRating
FROM shopInfo si
JOIN rating r ON r.shopId=si.id
WHERE si.shopId = '2'
group by
si.shopOpen

Aggregating queries by maximum count (MYSQL)

I have a follow table like so:
id eventid user
1 1 ABC
2 4 XYZ
3 4 DEF
4 1 XYZ
5 1 DEF
And an event table like so:
eventid title desc
1 tuv Lorem Ipsum
2 yfc Lorem Ipsum
3 jhk Lorem Ipsum
4 lmn Lorem Ipsum
I want a query that would output the list of popular events based ordered by the highest number of followers of that event.
For ecample, eventid 1 has the highest number of followers so that will be listed first and second will be event with eventid=4
select t1.eventid,t1.count(t1.eventid) as count_followers
from table_name t1 inner join events_table t2
on t1.eventid=t2.eventid group by t1.eventid order by count_followers desc

How do I efficiently find and keep a log of duplicate tweets in my database?

Please consider the following "tweets" table:
tweet_id user_id text
----------------------------
1 1 lorem ipsum
2 1 lorem ipsum
3 2 pear
4 1 dolor
5 3 foo
6 1 dolor
7 1 dolor
8 3 bar
9 3 baz
10 4 happy
11 4 happy
12 2 apple
13 3 foo
14 4 happy
In reality, the table contains millions of tweets from about 80,000 users. Many of there users are spam accounts, but they are hard to identify by hand. As a rule of thumb, spam accounts post the same message at least 3 times. That's why I want to fill the following tables, "duplicates" on the left and "duplicates_tweets" on the right:
duplicate_id user_id text cnt duplicate_id tweet_id
-------------------------------------- ----------------------
1 1 lorem ipsum 2 1 1
2 1 dolor 3 1 2
3 2 pear 1 2 4
4 2 apple 1 2 6
5 3 foo 2 2 7
6 3 bar 1 3 3
7 3 baz 1 4 12
8 4 happy 3 5 5
5 13
6 8
7 9
8 10
8 11
8 14
I can now very easily sort on cnt for instance, and see which users post the most duplicate messages. My question however, is how to go about this most efficiently. In other words: what query would be most efficient to fill these tables? And is it possible with just SQL or should I use PHP as an intermediary, for instance to take a tweet from the "tweets" database, scans for duplicates, fills the tables, and moves on to the next tweet? I'm afraid this would take ages to finish, so any help is greatly appreciated!
Probably, you could sort the table "tweets" by user_id and then by text:
SELECT * FROM tweets ORDER BY user_id DESC, text DESC
Afterwards you can iterate over the results in PHP:
<?php
// ...
$lastuser = -1;
$lasttext = "";
$ids = array();
while ($row = mysql_fetch_assoc($result)) {
if($row['user_id'] != $lastuser || $row['text'] != $lasttext) {
$ids = array();
}
$ids[] = $row['id'];
if(count($ids) >= 3) {
// flag items as spam
}
$lastuser = $row['user_id'];
$lasttext = $row['text'];
}
?>
If you use indexes in your MySQL database, you should be able to process N tweets in approximately N*log(N).
You can use the REPLACE function in MySQL to UPDATE or INSERT a new row based on the key:
REPLACE duplicates
SELECT user_id, text
FROM (SELECT user_id, text, count(1) as count
FROM tweets
GROUP BY user_id, text
HAVING count(1) > 2))
I agree with what #MichaelRushton and #Kosta answered but I am wondering if you shouldn't need another table at all? If you build the query, you can ask the first table for the knowledge you are seeking. I especially like the trigger.
Do you just want to pull out a list of possible spam tweets? Try this:
SELECT
user_id,
text,
COUNT(DISTINCT tweet_id)
FROM
tweets
GROUP BY
user_id,
text
HAVING
COUNT(DISTINCT tweet_id) >= 3
You can then use PHP to iterate over the result and INSERT/UPDATE a duplicate_tweets table (although as Chris K mentioned, do you really need a duplicate_tweets table when you can just use this query?).
Before you insert new tweet, check tweets table whether such tweet already exists. If so, insert tweet and insert it in duplicates and duplicates_tweets tables. Or use triggers on insert for tweets table.

Help with limiting a joined mysql database query

I have written a query which returns all records with some many-to-many joins correctly for the entire set or an individual article using WHERE a.id = ?
SELECT a.id, date_added, title, content, category_id, person_id, organization_id, c.name AS category_name, firstname, lastname, o.name AS organization_name
FROM articles AS a
LEFT OUTER JOIN articles_categories AS ac ON a.id=ac.article_id
LEFT OUTER JOIN categories AS c ON c.id=ac.category_id
LEFT OUTER JOIN articles_people AS ap ON a.id=ap.article_id
LEFT OUTER JOIN people AS p ON p.id=ap.person_id
LEFT OUTER JOIN articles_organizations AS ao ON a.id=ao.article_id
LEFT OUTER JOIN organizations AS o ON o.id=ao.organization_id
ORDER BY date_added
BUT!
I've hit a brick wall trying to work out how to limit the articles to a specific number of IDs, for working with pagination.
I'm ideally trying to use as simple and clear SQL statements as possible because I'm using the codeigniter framework with their active record class.
http://codeigniter.com/user_guide/database/active_record.html
Would really appreciate some help as I don't want to revert to using multiple queries for this as I've tried to reduce it down to a single query for database efficiency.
Have search around and tried some alternatives but nothing seems to work. Many thanks!
For example the results I return are like this
---------------------------------------------------------------------
id title category_id person_id organization_id
---------------------------------------------------------------------
1 test 1 1 1
1 test 2 1 1
1 test 1 2 1
1 test 1 1 2
1 test 5 1 1
1 test 8 1 1
1 test 1 4 1
1 test 1 4 2
1 test 1 1 1
2 test 2 2 1 1
2 test 2 1 2 1
2 test 2 1 1 2
2 test 2 5 1 1
2 test 2 8 1 1
2 test 2 1 4 1
2 test 2 1 4 2
I need the results like this so that I can create sub-arrays in the php like this:
$articles = $query->result_array();
$output = array();
foreach ($articles as $article) {
// set up article details
$article_id = $article['id'];
// add article details
$output[$article_id]['article_id'] = $article_id;
$output[$article_id]['date_added'] = $article['date_added'];
$output[$article_id]['title'] = $article['title'];
$output[$article_id]['content'] = $article['content'];
// set up people details and add people array with details if exists
if (isset($article['person_id'])) {
$person_id = $article['person_id'];
$output[$article_id]['people'][$person_id]['person_id'] = $person_id;
$output[$article_id]['people'][$person_id]['lastname'] = $article['lastname'];
$output[$article_id]['people'][$person_id]['firstname'] = $article['firstname'];
}
// set up organizations details and add organizations array with details if exists
if (isset($article['organization_id'])) {
$organization_id = $article['organization_id'];
$output[$article_id]['organizations'][$organization_id]['organization_id'] = $organization_id;
$output[$article_id]['organizations'][$organization_id]['organization_name'] = $article['organization_name'];
}
// set up categories details and add categories array with details if exists
if (isset($article['category_id'])) {
$category_id = $article['category_id'];
$output[$article_id]['categories'][$category_id]['category_id'] = $category_id;
$output[$article_id]['categories'][$category_id]['category_name'] = $article['category_name'];
}
}
But if I just use LIMIT (with offset etc) 1
the results I get are
---------------------------------------------------------------------
id title category_id person_id organization_id
---------------------------------------------------------------------
1 test 1 1 1
instead of
---------------------------------------------------------------------
id title category_id person_id organization_id
---------------------------------------------------------------------
1 test 1 1 1
1 test 2 1 1
1 test 1 2 1
1 test 1 1 2
1 test 5 1 1
1 test 8 1 1
1 test 1 4 1
1 test 1 4 2
1 test 1 1 1
which is my desired result.
OK, so finally I worked out how it is possible.
Thought i'd include it here in case anyone else has the same problem.
Changing this line
FROM articles AS a
to this
FROM (SELECT * FROM articles LIMIT 5,3) AS a
does what I wanted.
So, why don't you use OFFSET 0,10 and LIMIT *number_of_results* in the SQL Query? (if I understood the question)
Specific number of IDs... WHERE ID IN (2,4,6,8)... ?
Are you using codeigniter's pagination?
http://codeigniter.com/user_guide/libraries/pagination.html
You can easily limit the number of records that are being returned using the MySQL LIMIT clause. This can be achieved like the following with your sample query.
SELECT a.id, date_added, title, content, category_id, person_id, organization_id, c.name AS category_name, firstname, lastname, o.name AS organization_name
FROM articles AS a
LEFT OUTER JOIN articles_categories AS ac ON a.id=ac.article_id LEFT OUTER JOIN categories AS c ON c.id=ac.category_id
LEFT OUTER JOIN articles_people AS ap ON a.id=ap.article_id LEFT OUTER JOIN people AS p ON p.id=ap.person_id
LEFT OUTER JOIN articles_organizations AS ao ON a.id=ao.article_id LEFT OUTER JOIN organizations AS o ON o.id=ao.organization_id
ORDER BY date_added
LIMIT 10
Where 10 is the number of records you wish to display. The MySQL LIMIT clause allows you to specify a limit of the number of records and an initial offset. Like so:
LIMIT <offset>,<limit>
In your case <offset> would be the current page * the number of records on a page. <limit> would be the number of records you would like to display per page.

Categories