Select Count and Then Order By - mysql

I am having some problems trying to find the members with the most referrals.. I have been looking up stuff and trying stuff for more than 3 hours so this is my last resort. My goal is to list the members username and the amount of referrals they have..
So each members referral is marked by their id..
so in the example test2 is orig's ref. So each persons ref is marked by their id.
id | username | ref
1 | orig |0 (for none)
2 | test2 |1 (orig id)
3 | another |1 (orig id)
and the goal is to echo this out. If it is even possible.
UserName | Refs
test 1
test2 0
my attempt. It gives me the amount but it does not order them and echoes to many.
$result = mysql_query("SELECT * FROM members");
echo '<table class="table table-bordered"><tr><th>Credits</th><th>Username</th></tr>';
while($row = mysql_fetch_array($result))
{
$contest_id = $row['id'];
$result1 = mysql_query("SELECT COUNT(*) FROM members WHERE ref=".$row['id']."");
while($row1=mysql_fetch_array($result1))
{
$result_c = mysql_query("SELECT * FROM members ORDER BY ".$row1['COUNT(*)']."+0 DESC Limit 10");
while($row_c = mysql_fetch_array($result_c))
{
$top_id = $row_c['id'];
$find_c = mysql_query("select count(*) from members where user_id='$top_id'");
$found_c = mysql_result($find_c,0);
echo '<tr><td>';
echo $found_c;
echo '</td>';
echo '<td>';
echo $row_c['username'];
echo '</td>';
echo '</tr>';
}}}
echo '</table>';

If I understood your table lay-out correctly, this should do the trick.
SELECT t1.username, t2.numref
FROM members t1
LEFT JOIN (SELECT ref, COUNT(ref) as numref
FROM members
GROUP BY ref) t2
ON t2.ref = t1.id
ORDER BY numref DESC
It should provide a NULL value in the numref column for the users that haven't made any referrals.
For reference, I added a SQL-Fiddle!

Related

How to query CodeIgniter in two table with condition?

I got headache of this query issue in CodeIgniter
I'm a beginner of this framework
How to query in CodeIgniter of Query result in Table 1 and Table 2.
If you are using the Query Builder in Codeigniter version 3 (I assume since your using the tag codeigniter-3), then you could specify the columns in your select statement and use join to achieve what you want:
$this->db->select('t1.Account, t1.Client, t1.Wala, t2.Meron');
$this->db->from('Table1 t1');
$this->db->join('Table2 t2', 't1.Account = t2.Account AND t1.Client = t2.Client');
$this->db->where('t1.Account', 111); // IF YOU ONLY WANT A SPECIFIC ACCOUNT
$this->db->group_by('t1.Account, t1.Client');
$query = $this->db->get();
if ($query->num_rows() > 0){
$result = $query->result(); // ARRAY OF OBJECTS
foreach ($result as $r){
echo $r->Account."\t";
echo $r->Client."\t";
echo $r->Wala."\t";
echo $r->Meron."\n";
}
}
The result:
| Account | Client | Wala | Meron |
|---------|--------|------|-------|
| 111 | Doe | | 50 |
| 111 | Jhon | 200 | 50 |
Documentation: https://www.codeigniter.com/userguide3/database/query_builder.html
Alternatively, you can use a pure SQL query to get the same result:
$sql = 'SELECT t1.Account, t1.Client, t1.Wala, t2.Meron
FROM Table1 t1
JOIN Table2 t2
ON t1.Account = t2.Account AND t1.Client = t2.Client
WHERE t1.Account = 111
GROUP BY t1.Account, t1.Client';
$query = $this->db->query($sql);
If you are using MySQL > 5.6 then use the group by function any_value():
t1.Account, t1.Client, ANY_VALUE(t1.Wala), ANY_VALUE(t2.Meron)
To be used with caution since unexpected results may appear if you have multiple rows with different values in the columns "Wala" or "Meron" for the same Account and Client.

How to query rows from 2 tables in a single query?

TABLE 1
student_id | name
-----------------
1 | A
2 | B
3 | C
4 | D
TABLE 2
vote_id | student_id | vote_for
------------------------------
1 | 1 | 2
2 | 1 | 3
3 | 2 | 1
4 | 1 | 4
How can I get records from TABLE 1 (student names B C D) based on student_id in TABLE 2 (student_id 1) in a single query? I managed to do it but in multiple queries like below:
$students = array();
$query = "SELECT vote_for FROM table2 WHERE student_id=?";
$stmt = $this->con->prepare($query);
$stmt->bind_param("i",$student_id);
$stmt->execute();
$stmt->bind_result($vote_for);
$votes = array();
while($stmt->fetch()){
$votes[] = $vote_for;
}
$stmt->close();
if (!empty($votes)) {
$query = "SELECT name FROM table1 WHERE student_id=?";
foreach ($votes as $vote) {
$stmt = $this->con->prepare($query);
$stmt->bind_param("i",$vote);
$stmt->execute();
$stmt->bind_result($name);
while($stmt->fetch()){
$temp = array();
$temp['name'] = $name;
$students[] = $temp;
}
$stmt->close();
}
}
You can use a JOIN query to get the names of the students that were voted for by a given student_id. For example:
SELECT s.name AS voted_for
FROM table2 v
JOIN table1 s ON s.student_id = v.vote_for
WHERE v.student_id = 1
Demo on dbfiddle
In PHP:
$students = array();
$query = "SELECT s.name AS voted_for
FROM table2 v
JOIN table1 s ON s.student_id = v.vote_for
WHERE v.student_id = ?";
$stmt = $this->con->prepare($query);
$stmt->bind_param("i",$student_id);
$stmt->execute();
$stmt->bind_result($name);
while($stmt->fetch()) {
$students[] = array('name' => $name);
}
$stmt->close();
I believe you can achieve it with the following query:
SELECT T1.STUDENT_ID, T1.NAME
FROM TABLE_1 T1, TABLE_2 T2
WHERE T1.STUDENT_ID = T2.VOTE_FOR
AND T2.STUDENT_ID = ?
And you would just inject the STUDENT_ID for the Table 2. You can remove the T1.STUDENT_ID if necessary.

how to Collect data from two tables using joins

I have 2 tables
table 1 structure: [ logs ]
userid || clicks || date || XXX || XXX |||
table 2 structure : [ user ]
username || email || date || XXX || XXX |||
I want to display data like this
username, COUNT(clicks)
I am using the query below.
SELECT `user.username`,`userid`, COUNT(`userid`) as `total`
FROM `logs`
INNER JOIN user ON logs.userid=user.userid
ORDER BY total DESC
LIMIT 5
Kindly quide
After the first reply , I modifed the query and aplied it , like this
$sqlptcwall=mysql_query("SELECT user.username, COUNT(ptcwalllogs.userid) AS total FROM logs INNER JOIN user ON user.userid = ptcwalllogs.userid GROUP BY user.username ORDER BY COUNT(ptcwalllogs.userid) DESC
LIMIT 5");
<?php
echo "</tr>";
while($row = mysql_fetch_array($sqlptcwall))
{
echo "<tr> ";
echo "<td>" .$row[userid] . "</td>";
echo "<td>" .$row[total] . "</td>";
}
echo "</tr> " ;
?>
Error:
mysql_fetch_array() expects parameter 1 to be resource, boolean given in
SELECT user.username, COUNT(user.userid) AS total
FROM logs
INNER JOIN user ON user.userid = logs.userid
GROUP BY user.username
ORDER BY COUNT(user.userid) DESC
LIMIT 5

Select rows from a table where all values of an array exist

I have this query that retreives a list of id's + NAME:
$sql = "SELECT id FROM #__table1 ";
$sql .= " WHERE (";
foreach($explode_tags as $k=>$explode_tag) {
$sql .= "name = ".$db->Quote(trim($explode_tag));
if(($k+1) != count($explode_tags))
$sql .= " OR ";
}
$sql .= ")";
$db->setQuery($sql);
$results = $db->loadResultArray();
The result is an array like this:
keywordID | NAME
1 cat
2 dog
3 horse
Now I have this table2:
id | ItemID | keywordID
1 4 1
2 4 2
3 4 3
4 6 1
5 6 2
6 7 1
I want to find from table2 all ItemID's that have all keywordID's found in table1.
In the example above I want to return only itemID 4 that has all keywords (all 3 of them).
I am running this query but I am not getting results:
...
$query .= " AND i.id IN (SELECT itemID FROM #__table2 WHERE (";
foreach($results as $k=>$result) {
$query .= "keywordID = ".(int)$result;
if(($k+1) != count($results))
$query .= " AND ";
}
$query .= "))";
UPDATE
Sorry, I miss read your question. I've done simple test using this data:
id itemId keywordId
1 4 1
5 4 2
6 4 3
7 5 2
8 5 3
9 6 1
10 6 2
11 6 3
12 7 3
13 9 3
14 9 2
15 9 1
and using this query:
SELECT itemId, GROUP_CONCAT( keywordId ORDER BY keywordId ) AS crpcnct, COUNT( itemId )
FROM `temporary_table_123`
GROUP BY 1
HAVING crpcnct = '1,2,3'
I can get the value that you wanted:
itemId crpcnct count(itemId)
4 1,2,3 3
6 1,2,3 3
9 1,2,3 3
To achieve this, all you have to do is build the keywordID you want to use:
$keywordIds[] = $results['keywordId'];
and then sort accending
sort($keywordIds);
the last step is, supply this array into query:
SELECT itemId, GROUP_CONCAT( keywordId ORDER BY keywordId ) AS crpcnct, COUNT( itemId )
FROM `temporary_table_123`
GROUP BY 1
HAVING crpcnct = '" . implode(",", $keywordIds) . "'
There you have it.
SELECT ItemID FROM table2 WHERE keywordID IN (SELECT keywordID FROM table1)
This might work. I'll have to create local copies of your tables to see for sure, though.
$array_names = array();
foreach($explode_tags as $k=>$explode_tag){
$array_names[] = 'name = ' . $db->Quote(trim($explode_tag));
}
$sql = "SELECT ItemID FROM table_2 WHERE keywordID IN (SELECT keywordID FROM table_1 WHERE " . implode(' OR ', $array_names) .")";
$db->setQuery($sql);
$results = $db->loadResultArray();

how to get records in the following scenario

I have a table like below :
node_name id term_name
----------------------------------------------
test1 001 physics
test1 001 maths
test1 001 chemistry
test2 002 physics
test2 002 maths
Given a combination of term names I want to find all rows where the id set only contains exactly the given term names.
For example given the term names physics & maths my output should be like below
node_name id term_name
----------------------------------------------
test2 002 physics
test2 002 maths
Id set 001 contains also chemistry that is why it should not be included.
Your question: get all rows where no other rows with same id but other term_names exists
SELECT * FROM <table> x WHERE
term_name IN ('physics','maths') AND
NOT EXISTS (SELECT * FROM <table> WHERE id=x.id AND term_name NOT IN ('physics','maths'))
first of all you need to parse your query to convert the '&' to SQL 'OR' operator
in PHP :
//Parse the query
$arr = explode('&',$query);
$where = '';
//get the term count
$count = count($arr);
foreach($arr as $value){
$where .= "term_name = '" . $value . "' OR";
}
//Remove last or
$where = rtrim($where,'OR');
then :
use L
"select node_name ,count(1) as Total from my table where $where
group by node_name
having Total =" . $count
Finally :
your query must be in this format:
select x,count(1) as total from mytable where field1 = 'term1' or field1 = 'term2' having total = 2
One possible way to do this:
select id, node_name
from nodes join
(select id,
count(*)
from nodes
where node_name in ('physics','math')
group by id
having count(*) = 2 // this is set when generating the query ) as eligible_nodes
on nodes.id = eligible_nodes.id