I have following Problem
SELECT * from map_user_sticker WHERE map_user_sticker.user_id = 7;
+----+---------+------------+
| id | user_id | sticker_id |
+----+---------+------------+
| 35 | 7 | 55 |
| 3 | 7 | 30 |
| 32 | 7 | 49 |
| 33 | 7 | 52 |
| 34 | 7 | 43 |
| 36 | 7 | 50 |
+----+---------+------------+
6 rows in set (0.00 sec)
SELECT * FROM sticker;
+----+--------------------------------------------------+
| id | word |
+----+--------------------------------------------------+
| 40 | I love Sonal |
| 41 | Add User to Database |
| 39 | This is a dream Project |
| 33 | Narendra Sisodiya |
| 34 | Sourabh Parmar |
| 30 | Sonal Sisodiya |
| 42 | I love India |
| 43 | I love Linux |
| 44 | I hate Congress |
| 45 | I love jQuery |
| 48 | Modi will be the PM |
| 47 | Ramdev Baba is my Super Hero |
| 49 | हिन्दी से प्यार है |
| 50 | Linux is better then Windows |
| 52 | I am from Sehore |
| 55 | I have 2 little kids - sadu and sonu |
+----+--------------------------------------------------+
16 rows in set (0.00 sec)
I basically want to generate Result like
+----+--------------------------------------------------+----------+
| id | word | present |
+----+--------------------------------------------------+----------+
| 40 | I love Sonal | 0 |
| 41 | Add User to Database | 0 |
| 39 | This is a dream Project | 0 |
| 33 | Narendra Sisodiya | 0 |
| 34 | Sourabh Parmar | 0 |
| 30 | Sonal Sisodiya | 1 |
| 42 | I love India | 0 |
| 43 | I love Linux | 1 |
| 44 | I hate Congress | 0 |
| 45 | I love jQuery | 0 |
| 48 | Modi will be the PM | 0 |
| 47 | Ramdev Baba is my Super Hero | 0 |
| 49 | हिन्दी से प्यार है | 1 |
| 50 | Linux is better then Windows | 1 |
| 52 | I am from Sehore | 1 |
| 55 | I have 2 little kids - sadu and sonu | 1 |
+----+--------------------------------------------------+----------+
16 rows in set (0.00 sec)
Please Help me !!
I want to generate a extra column called "present", based on following condition
If sticker_id from query1 == id from query 2 then present = 1
else present = 0
Here the Answer I was wanted to get !
Answer 1 -
SELECT s.* , IF(FIND_IN_SET(7,(GROUP_CONCAT(m.user_id))) != 0 , 1,0) as present, COUNT(m.user_id) as totalUsers
FROM sticker s
LEFT JOIN map_user_sticker m
ON s.id = m.sticker_id
GROUP BY id;
Answer 2 -
SELECT id,word, (case when 7 in (select user_id from map_user_sticker WHERE map_user_sticker.sticker_id=sticker.id) then 1 else 0 end) as present
from sticker;
I don,t know which one is fast and better
Try this:
select id,word,
case(when id in (select sticker_id from map_user_sticker) then 1 else 0 end)
as present from sticker;
Hope, this will help:
SELECT sticker.id, sticker.word, (IF(sticker_id IS NULL, 0, 1)) AS present FROM sticker LEFT JOIN map_user_sticker ON (sticker.id = map_user_sticker.sticker_id)
Try this query -
SELECT s.*, IF(COUNT(m.sticker_id) > 0, 1, 0) present FROM sticker s
LEFT JOIN map_user_sticker m
ON s.id = m.sticker_id
GROUP BY
s.id;
Is this what you want?
SELECT s.*, IF(m.sticker_id IS NULL, 0, 1) present FROM sticker s
LEFT JOIN map_user_sticker m
ON s.id = m.sticker_id
WHERE m.user_id = 7;
Related
I have two tables:
1. SELECT * FROM gas_trades_bids;
+----+---------+----------+--------+------------+------------+
| id | user_id | claim_id | amount | lots_value | timestmp |
+----+---------+----------+--------+------------+------------+
| 5 | 9 | 11 | 60 | NULL | 1571317861 |
| 6 | 9 | 11 | 100 | NULL | 1571656888 |
| 7 | 9 | 11 | 50 | NULL | 1571727353 |
| 8 | 9 | 11 | 50 | NULL | 1571918296 |
+----+---------+----------+--------+------------+------------+
4 rows in set (0.00 sec)
2. SELECT * FROM gas_trades_offers;
+----+---------+----------+--------+------------+----------+------------+
| id | user_id | claim_id | amount | lots_value | accepted | timestmp |
+----+---------+----------+--------+------------+----------+------------+
| 8 | 9 | 11 | 33 | 22 | NULL | 1571918576 |
| 9 | 9 | 11 | 33 | 22 | 1 | 1571918576 |
| 10 | 9 | 11 | 33 | 22 | 1 | 1571918576 |
+----+---------+----------+--------+------------+----------+------------+
3 rows in set (0.01 sec)
The goals are:
Count the amount of the rows where gas_trades_bids.claim_id = gas_trades_offers_claim_id and gas_trades_bids.claim_id = 11 and gas_trades_bids.user_id = 11
Get the sum of the column gas_trades_offers.lots_value values
To reach this I tried to run:
SELECT COUNT(bids.id) amount, SUM(offers.lots_value)
FROM gas_trades_offers offers, (SELECT * FROM gas_trades_bids) bids
WHERE bids.user_id = 9
AND bids.user_id = offers.user_id
But I've got the multiple rows:'
+--------+------------------------+
| amount | SUM(offers.lots_value) |
+--------+------------------------+
| 3 | 66 |
| 3 | 66 |
| 3 | 66 |
| 3 | 66 |
+--------+------------------------+
4 rows in set (0.01 sec)
What do I do in the wrong way?
I have expected to get only:
+--------+------------------------+
| amount | SUM(offers.lots_value) |
+--------+------------------------+
| 3 | 66 |
+--------|------------------------|
I don't need to use GROUP BY!
Is it exactly what you need? Hope that this query can work well.
SELECT COUNT(offers.id) amount,
SUM(offers.lots_value)
FROM gas_trades_offers offers
WHERE offers.user_id = 9 and offers.claim_id = 11
AND exists (SELECT id FROM gas_trades_bids bids WHERE bids.claim_id = offers.claim_id and bids.user_id = offers.user_id)
Try this:
SELECT COUNT(bids.id) amount,
SUM(offers.lots_value)
FROM gas_trades_offers offers
JOIN gas_trade_bids bids ON bids.user_id = offers.user_id
WHERE offers.user_id = 9;
I am working on a project that rewards people base on referrals (MLM)
I have been able to count the total number of child nodes on both left and right side but now I need to be able to update the ranks of users when they have a certain number of users with certain ranks below them on both sides. (I will explain better below:
User Table
id | name | parentID| side | rank |
4 | Dan | | | starter|
5 | Chris | 4 | left | starter|
6 | James | 4 | right| starter|
7 | Tybe | 5 | left | starter|
8 | Rose | 5 | right| starter|
9 | Paul | 6 | left | starter|
10 | Zach | 6 | right| starter|
Tree table
userID | left | right| leftCount | rightCount|
4 | 5 | 6 | 3 | 3 |
5 | 7 | 8 | 1 | 1 |
6 | 9 | 10 | 1 | 1 |
7 | | | 0 | 0 |
8 | | | 0 | 0 |
9 | | | 0 | 0 |
10 | | | 0 | 0 |
Below is the tree generated from this table
How i update the leftCount and rightCount when a user registers
$referralid; //who is referring the current user
$side; //the side the user is to fall under, either left or right
$temp_referralid = $referralid;
$temp_sideCount = $side.'Count'; //leftCount or rightCount
$temp_side = $side;
$total_count=1;
$i=1;
while($total_count>0){
$stmt = $db->prepare("SELECT * from tree WHERE id=:id");
$stmt->bindValue(':id', $temp_referralid);
$stmt->execute();
$r = $stmt->fetch(PDO::FETCH_ASSOC);
$current_temp_sideCount = ($r[$temp_sideCount]+1);
//This will add (+1) to the leftCount or rightCount
//of the referral depending on the side the user
//choose to fall under.
$sql ="UPDATE `tree` SET `$temp_sideCount`=:count WHERE `id` = :id";
$stmt = $db->prepare($sql);
$stmt->bindValue(':count', $current_temp_sideCount);
$stmt->bindValue(':id', $temp_referralid);
$stmt->execute();
//if the user has someone that referred them as
//only the last person at the top has no referral
if($temp_referralid!=""){
//change the $referralid to the person that referred the person
//referring this user. this is where the loop will go through
//to the last person maintaining the side upward
$next_referralid = $this->getReferringId($db, $temp_referralid);
$temp_side = $this->getReferringIdSide($db, $temp_referralid);
$temp_sideCount = $temp_side.'Count';
$temp_referralid = $next_referralid;
$i++;
}else{
$total_count=0;
}
}
}
Functions used
getReferringId($db, $id) //gets the referringId of the user passed as
//param from the user table
getReferringIdSide($db, $id) //gets the side which the user
//is on (left or right) from the user table
All this is working just fine but then I need to implement something and I haven’t found the best way around it.
I need to keep changing the rank for each user if they have attained a stage. see below and example:
stage 1: starter //just registered
stage 2: grow // the person has leftCount=3 and rightCount=3
stage 3: growbig //the person has 7 - grow user on the left
//and 7- grow user on the right
state 4: growbigger //the person has 7 - growbig on left and 7 growbig
//on the right
Up to stage 2, I have no problem but upwards is where I cant get my hands on the right logic
Update
for example: The numbers of growbig's can come from anywhere on the legs, it shouldn’t just be direct nodes, just a count of ranks all below that user on each sides
UPDATE: Re-asking in a clearer term and specifications
its a binary tree (2:2) which means a person can only have two people directly under them (one on the left and another on the right.
With the picture above my table looks like this
Tree table
userID | left (userid) | right (userid)| rank
8 | 4 | 12 |
4 | 2 | 6 |
12 | 10 | 14 |
2 | 1 | 3 |
6 | 5 | 7 |
10 | 9 | 11 |
14 | 14 | 15 |
Note: its not compulsory for a user to have anyone under him on any side or both. it means if a user have nobody under him then the tree (branch) ends there, if he has one person directly on the left and none on the right it means the left branch can continue to grow.
The logic to grade each user base on their growths and how they have managed to balance the growth on each side is the problem.
The logic
Rank 1: supervisor: user must have at 3 users on its right branch and 3 users on the left branch.
Rank 2: controller: user must have 7 users who are 'supervisors' on it's left and 7 users who have become supervisors on the right too.
Rank 3: Senior Controller: user must have 7 users who are 'controller' on the left branch and have 7 'controller' on the right too.
Rank 4: Ambassador: user must have 7 users who are senior controller on its left and 7 senior controllers on the right
Rank 5: Senior Ambassador: user must have 7 users who are ambassadors on the left and same on the right.
Rank 6: Grand Ambassador: user must have 7 users who are senior ambassadors on his both sides.
Explanation:
let me pick on rank and explain it:
Rank: Ambassador- if user with ID 3 has 45 people on its right hand side and 7 of the people on its right branch are senior controllers and also on the left he has 67 people and 7 are already senior controllers then user with ID 3 should be upgraded to 'ambassador'
#blag
This is more likely how I would take this problem (using http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ ):
The new table schema is :
'id'| 'name' | 'left'| 'right'| 'rank'
4 | 'Dan' | 1 | 14 | 'starter'
5 | 'Chris'| 2 | 7 | 'starter'
6 | 'James'| 8 | 13 | 'starter'
7 | 'Tybe' | 3 | 4 | 'starter'
8 | 'Rose' | 5 | 6 | 'starter'
9 | 'Paul' | 9 | 10 | 'starter'
10 | 'Zach' | 11 | 12 | 'starter'
The full version :
Note, I use the following value to avoid using a bigger dataset
-- on each side
set #grow = 1 // -- 1 child R & L
set #growbig = 2 // -- 2 grow child R & L
SQL Fiddle
PROCEDURE
CREATE PROCEDURE p(IN p_parent varchar(15), IN p_children varchar(15))
BEGIN
IF NOT EXISTS (
select parent.*, count(distinct dc.id) direct_child
from u parent
left join u as dc on(parent.left=dc.left-1 or parent.right=dc.right+1)
WHERE parent.name = p_parent
group by parent.id
having count(distinct dc.id) =2
)
THEN
SET #myLeft =(SELECT `left` FROM u WHERE name = p_parent);
UPDATE u SET `right` = `right` + 2 WHERE `right` > #myLeft;
UPDATE u SET `left` = `left` + 2 WHERE `left` > #myLeft;
INSERT INTO u(`name`, `left`, `right`)
VALUES(p_children, #myLeft + 1, #myLeft + 2);
END IF;
END
//
call p('Tybe','Marjorie') //
call p('Tybe','Vernon') //
call p('Rose','Marc') //
call p('Rose','Peter') //
call p('Marc','Lily') //
call p('Marc','Ignotus') //
call p('Ignotus','Aragorn') //
call p('Ignotus','Arwen') //
call p('Peter','Chase') //
call p('Peter','Foreman') //
call p('Chase','Pétunia') //
call p('Chase','Dudley') //
call p('Foreman','Bob') //
call p('Foreman','Taub') //
call p('Paul','Lisa') //
call p('Paul','Bilbo') //
call p('Lisa','House') //
call p('Lisa','Gandalf') //
call p('Gandalf','Frodo') //
call p('Gandalf','Legolas') //
call p('House','Thirteen') //
call p('House','Wilson') //
call p('Thirteen','Ginny') //
call p('Thirteen','Harry') //
call p('Wilson','Kutner') //
call p('Wilson','Master') //
call p('Master','Adams') //
call p('Master','Park') //
call p('Zach','Ary') //
grow
set #grow = 1 //
update u
set rank = 'grow'
where u.id in (
select id from (
select id
from (
select p.id id, p.name name, lc.id lcid, null rcid
from u p
inner join u l on (p.left = l.left-1 and p.right <> l.right+1)
inner join u lc on (lc.left >= l.left and lc.right <= l.right)
inner join u r on (p.right = r.right+1 and p.left <> r.left-1)
union all
select p.id id, p.name name, null lcid, rc.id rcid
from u p
inner join u l on (p.left = l.left-1 and p.right <> l.right+1)
inner join u r on (p.right = r.right+1 and p.left <> r.left-1)
inner join u rc on (rc.left >= r.left and rc.right <= r.right)
) p
group by p.id
having
count(distinct lcid) >= #grow
and count(distinct rcid) >= #grow
) z
)
//
growbig
set #growbig = 2 //
update u
set rank = 'growbig'
where u.id in (
select id from (
select id
from (
select p.id id, p.name name, lc.id lcid, null rcid
from u p
inner join u l on (p.left = l.left-1 and p.right <> l.right+1)
inner join u lc on (lc.rank ='grow' and lc.left >= l.left and lc.right <= l.right)
inner join u r on (p.right = r.right+1 and p.left <> r.left-1)
union all
select p.id id, p.name name, null lcid, rc.id rcid
from u p
inner join u l on (p.left = l.left-1 and p.right <> l.right+1)
inner join u r on (p.right = r.right+1 and p.left <> r.left-1)
inner join u rc on (rc.rank ='grow' and rc.left >= r.left and rc.right <= r.right)
) p
group by p.id
having
count(distinct lcid) >= #growbig
and count(distinct rcid) >= #growbig
) z
)
//
Query 1:
-- output parent that have both right and left child
select parent.*, count(distinct dc.id) direct_child
from u parent
left join u as dc on(parent.left=dc.left-1 or parent.right=dc.right+1)
group by parent.id
having count(distinct dc.id) =2
Results:
| id | name | left | right | rank | direct_child |
|----|----------|------|-------|---------|--------------|
| 4 | Dan | 1 | 72 | growbig | 2 |
| 5 | Chris | 2 | 35 | grow | 2 |
| 6 | James | 36 | 71 | grow | 2 |
| 7 | Tybe | 3 | 8 | grow | 2 |
| 8 | Rose | 9 | 34 | growbig | 2 |
| 9 | Paul | 37 | 66 | grow | 2 |
| 13 | Marc | 24 | 33 | grow | 2 |
| 14 | Peter | 10 | 23 | grow | 2 |
| 16 | Ignotus | 25 | 30 | grow | 2 |
| 19 | Chase | 17 | 22 | grow | 2 |
| 20 | Foreman | 11 | 16 | grow | 2 |
| 25 | Lisa | 40 | 65 | grow | 2 |
| 27 | House | 47 | 64 | grow | 2 |
| 28 | Gandalf | 41 | 46 | grow | 2 |
| 31 | Thirteen | 58 | 63 | grow | 2 |
| 32 | Wilson | 48 | 57 | grow | 2 |
| 36 | Master | 49 | 54 | grow | 2 |
Query 2:
-- show the tree
SELECT CONCAT( REPEAT('|...', COUNT(parent.name) - 1), node.id, ' ', node.name,' /',node.rank) AS name
FROM u AS node,
u AS parent
WHERE node.left BETWEEN parent.left AND parent.right
GROUP BY node.name
ORDER BY node.left
Results:
| name |
|-----------------------------------------------|
|4 Dan /growbig |
||...5 Chris /grow |
||...|...7 Tybe /grow |
||...|...|...12 Vernon /starter |
||...|...|...11 Marjorie /starter |
||...|...8 Rose /growbig |
||...|...|...14 Peter /grow |
||...|...|...|...20 Foreman /grow |
||...|...|...|...|...24 Taub /starter |
||...|...|...|...|...23 Bob /starter |
||...|...|...|...19 Chase /grow |
||...|...|...|...|...22 Dudley /starter |
||...|...|...|...|...21 Pétunia /starter |
||...|...|...13 Marc /grow |
||...|...|...|...16 Ignotus /grow |
||...|...|...|...|...18 Arwen /starter |
||...|...|...|...|...17 Aragorn /starter |
||...|...|...|...15 Lily /starter |
||...6 James /grow |
||...|...9 Paul /grow |
||...|...|...26 Bilbo /starter |
||...|...|...25 Lisa /grow |
||...|...|...|...28 Gandalf /grow |
||...|...|...|...|...30 Legolas /starter |
||...|...|...|...|...29 Frodo /starter |
||...|...|...|...27 House /grow |
||...|...|...|...|...32 Wilson /grow |
||...|...|...|...|...|...36 Master /grow |
||...|...|...|...|...|...|...38 Park /starter |
||...|...|...|...|...|...|...37 Adams /starter |
||...|...|...|...|...|...35 Kutner /starter |
||...|...|...|...|...31 Thirteen /grow |
||...|...|...|...|...|...34 Harry /starter |
||...|...|...|...|...|...33 Ginny /starter |
||...|...10 Zach /starter |
||...|...|...39 Ary /starter |
Query 3:
-- show parent + child data
select *,(l.right - l.left -1)/2 l , (r.right - r.left -1)/2 r from u p
inner join u l on (p.left = l.left-1 and p.right <> l.right+1)
inner join u r on (p.right = r.right+1 and p.left <> r.left-1)
Results:
| id | name | left | right | rank | id | name | left | right | rank | id | name | left | right | rank | l | r |
|----|----------|------|-------|---------|----|---------|------|-------|---------|----|----------|------|-------|---------|----|----|
| 4 | Dan | 1 | 72 | growbig | 5 | Chris | 2 | 35 | grow | 6 | James | 36 | 71 | grow | 16 | 17 |
| 5 | Chris | 2 | 35 | grow | 7 | Tybe | 3 | 8 | grow | 8 | Rose | 9 | 34 | growbig | 2 | 12 |
| 6 | James | 36 | 71 | grow | 9 | Paul | 37 | 66 | grow | 10 | Zach | 67 | 70 | starter | 14 | 1 |
| 7 | Tybe | 3 | 8 | grow | 12 | Vernon | 4 | 5 | starter | 11 | Marjorie | 6 | 7 | starter | 0 | 0 |
| 8 | Rose | 9 | 34 | growbig | 14 | Peter | 10 | 23 | grow | 13 | Marc | 24 | 33 | grow | 6 | 4 |
| 13 | Marc | 24 | 33 | grow | 16 | Ignotus | 25 | 30 | grow | 15 | Lily | 31 | 32 | starter | 2 | 0 |
| 16 | Ignotus | 25 | 30 | grow | 18 | Arwen | 26 | 27 | starter | 17 | Aragorn | 28 | 29 | starter | 0 | 0 |
| 14 | Peter | 10 | 23 | grow | 20 | Foreman | 11 | 16 | grow | 19 | Chase | 17 | 22 | grow | 2 | 2 |
| 19 | Chase | 17 | 22 | grow | 22 | Dudley | 18 | 19 | starter | 21 | Pétunia | 20 | 21 | starter | 0 | 0 |
| 20 | Foreman | 11 | 16 | grow | 24 | Taub | 12 | 13 | starter | 23 | Bob | 14 | 15 | starter | 0 | 0 |
| 9 | Paul | 37 | 66 | grow | 26 | Bilbo | 38 | 39 | starter | 25 | Lisa | 40 | 65 | grow | 0 | 12 |
| 25 | Lisa | 40 | 65 | grow | 28 | Gandalf | 41 | 46 | grow | 27 | House | 47 | 64 | grow | 2 | 8 |
| 28 | Gandalf | 41 | 46 | grow | 30 | Legolas | 42 | 43 | starter | 29 | Frodo | 44 | 45 | starter | 0 | 0 |
| 27 | House | 47 | 64 | grow | 32 | Wilson | 48 | 57 | grow | 31 | Thirteen | 58 | 63 | grow | 4 | 2 |
| 31 | Thirteen | 58 | 63 | grow | 34 | Harry | 59 | 60 | starter | 33 | Ginny | 61 | 62 | starter | 0 | 0 |
| 32 | Wilson | 48 | 57 | grow | 36 | Master | 49 | 54 | grow | 35 | Kutner | 55 | 56 | starter | 2 | 0 |
| 36 | Master | 49 | 54 | grow | 38 | Park | 50 | 51 | starter | 37 | Adams | 52 | 53 | starter | 0 | 0 |
Query to get results from 2 tables:
SELECT path.* FROM (SELECT tbc.course_name
slp.course_id,slp.student_type,slp.stu_reference_id,
count(slp.course_id) as counttotalWatchedStudents
from tbl_student_learning_path slp LEFT JOIN tbl_courses tbc
on tbc.course_pid = slp.course_id WHERE slp.stu_reference_id =34
and slp.student_type='institute' GROUP BY slp.course_id ) as path
Query result table:
| course_id | totalCollegeStudents | fullwatchedStudentsCount | counttotalWatchedStudents | sumOfWatchPointsForWatchedStudents | totalStudentsAvg | fullwatchedAvg |
|-------------------------------|----------------------|--------------------------|---------------------------|------------------------------------|------------------|----------------|
| Number Systems | 9 | 0 | 3 | 60 | 20.0000 | 0 |
| Percentages | 9 | 0 | 3 | 30 | 10.0000 | 0 |
| Blood Relations | 9 | 3 | 3 | 300 | 100.0000 | 300 |
| Calandar | 9 | 3 | 3 | 300 | 100.0000 | 300 |
| Percentages | 9 | 3 | 3 | 300 | 100.0000 | 300 |
| Permutation & Combination | 9 | 3 | 3 | 300 | 100.0000 | 300 |
| Probability | 9 | 0 | 3 | 90 | 30.0000 | 0 |
| Ratios | 9 | 0 | 3 | 120 | 40.0000 | 0 |
| Time and Work | 9 | 0 | 3 | 150 | 50.0000 | 0 |
| Time Speed & Distance | 9 | 1 | 3 | 140 | 46.6667 | 100 |
| Averages | 9 | 3 | 3 | 300 | 100.0000 | 300 |
| Coding and Decoding | 9 | 3 | 3 | 300 | 100.0000 | 300 |
From the above table, i want to add inner query to the main query
query should be something like this:
( select count(t1.watched_percentage) from tbl_student_learning_path t1
WHERE t1.stu_reference_id =34 and t1.student_type='institute'
AND t1.watched_percentage >= 90 group by t1.course_id )
fullwatchedStudentsCount,
And the result should come like this(this is nothing but if first table counttotalWatchedStudents value is 3 it means that there are 2 type of people
1.students watched full (watched_percentage>=90)
2.students still watching (watched_percentage 1-89)
)
| fullwatchedStudentsCount | fullwatchedStudentsSum |
|--------------------------|------------------------|
| 2 | 200 |
| 1 | 100 |
| 0 | 0 |
| 2 | 200 |
| 1 | 100 |
| 1 | 100 |
| 0 | 0 |
| 2 | 200 |
| 2 | 200 |
| 1 | 100 |
| 2 | 200 |
| 1 | 100 |
If I understand correctly you want sum up the students which saw more than 90% in another column:
I'd do it like this:
SELECT tbc.course_name,
slp.course_id,
slp.student_type,
slp.stu_reference_id,
count(slp.course_id) AS counttotalWatchedStudents,
sum(if(slp.watched_percentage>=90, 1, 0)) AS fullwatchedStudentsCount
sum(if(slp.watched_percentage>=90, watched_percentage, 0)) AS fullwatchedStudentsSum
FROM tbl_student_learning_path slp
LEFT JOIN tbl_courses tbc ON tbc.course_pid = slp.course_id
WHERE slp.stu_reference_id =34
AND slp.student_type='institute'
GROUP BY slp.course_id
enter code here
Hope this helps
So you want to count students with a watched_percentage >= 90? Use conditional aggregation for this:
SELECT
tbc.course_name,
slp.course_id,
slp.student_type,
slp.stu_reference_id,
COUNT(*) as counttotalWatchedStudents,
SUM(slp.watched_percentage >= 90) as fullwatchedStudentsCount,
SUM(slp.watched_percentage < 90) as stillwatchedStudentsCount
FROM tbl_student_learning_path slp
LEFT JOIN tbl_courses tbc ON tbc.course_pid = slp.course_id
WHERE slp.stu_reference_id = 34
AND slp.student_type= 'institute'
GROUP BY slp.course_id;
MySQL treats true = 1 and false = 0, so you can simply sum the trues :-)
invoice table
SELECT id, fname, gtotal, `date` FROM invoice WHERE id = 1;
| id | fname | gtotal | date |
|----|---------|--------|-----------------------|
| 1 | Brandon | 860 | May, 11 2016 00:00:00 |
invoice_contents table,
SELECT * FROM invoice_contents WHERE invoice_id = 1;
| id | invoice_id | item | price | quantity | discount | total |
|----|------------|------------|-------|----------|----------|-------|
| 1 | 1 | Dextrose | 10 | 10 | 5 | 95 |
| 2 | 1 | Nescaine | 20 | 30 | 10 | 540 |
| 3 | 1 | Anticavity | 30 | 10 | 25 | 225 |
This JOIN query
SELECT invoice.id, invoice.fname, invoice_contents.item,
invoice_contents.price, invoice_contents.quantit,
invoice_contents.discount, invoice_contents.total,
invoice.gtotal
FROM invoice_contents
INNER JOIN invoice ON invoice_contents.invoice_id=1 AND invoice.id=1;
gives this result.
| id | fname | item | price | quantity | discount | total | gtotal |
|----|---------|------------|-------|----------|----------|-------|--------|
| 1 | Brandon | Dextrose | 10 | 10 | 5 | 95 | 860 |
| 1 | Brandon | Nescaine | 20 | 30 | 10 | 540 | 860 |
| 1 | Brandon | Anticavity | 30 | 10 | 25 | 225 | 860 |
I need this result.
| id | fname | item | price | quantity | discount | total | gtotal |
|----|---------|------------|-------|----------|----------|-------|--------|
| 1 | Brandon | Dextrose | 10 | 10 | 5 | 95 | 860 |
| | | Nescaine | 20 | 30 | 10 | 540 | |
| | | Anticavity | 30 | 10 | 25 | 225 | |
I am just a beginner in MySQL. I have been trying from this morning to get this kind of output by experimenting on different combinations please help me out.
#Rex, Your select is correct. You should make desired output using some script e.g. PHP.
try this in SQL:
in this Query i save everytime fname in a variable is not equal and at the next row i compare it and return a empty string is it equal. and the same for gtotal.
the cross join is only to initialize the variables.
in this case it is important that the rows are order by fname to ensure that the same name is behind each other
SELECT
invoice.id,
IF(#last_fname = invoice.fname, '', (#last_fname:=invoice.fname)) as fname,
invoice_contents.item,
invoice_contents.price,
invoice_contents.quantity,
invoice_contents.discount,
IF(#last_gtotal = invoice.gtotal, '', (#last_gtotal:=invoice.gtotal)) as gtotal
FROM invoice_contents
INNER JOIN invoice ON invoice_contents.invoice_id=1 AND invoice.id=1
CROSS JOIN ( select #last_fname := '' , #last_gtotal := '' ) AS parameter
ORDER BY invoice.fname;
Sample
MariaDB [bb]> SELECT
-> invoice.id,
-> IF(#last_fname = invoice.fname, '', (#last_fname:=invoice.fname)) AS fname,
-> invoice_contents.item,
-> invoice_contents.price,
-> invoice_contents.quantity,
-> invoice_contents.discount,
-> IF(#last_gtotal = invoice.gtotal, '', (#last_gtotal:=invoice.gtotal)) AS gtotal
-> FROM invoice_contents
-> INNER JOIN invoice ON invoice_contents.invoice_id=1 AND invoice.id=1
-> CROSS JOIN ( SELECT #last_fname:='' , #last_gtotal:='' ) AS parameter
-> ORDER BY invoice.fname;
+----+---------+------------+-------+----------+----------+--------+
| id | fname | item | price | quantity | discount | gtotal |
+----+---------+------------+-------+----------+----------+--------+
| 1 | Brandon | Dextrose | 10.00 | 10 | 5.00 | 860.00 |
| 1 | | Nescaine | 20.00 | 30 | 10.00 | |
| 1 | | Anticavity | 30.00 | 10 | 25.00 | |
+----+---------+------------+-------+----------+----------+--------+
3 rows in set, 1 warning (0.00 sec)
MariaDB [bb]>
I have a problem in making SQL query. I am making a small Search Engine in which the word to page mapping or indexes are kept like this.
Sorry I wasn't able to post images here so I tried writing the output like this.
+---------+---------+-----------+--------+
| word_id | page_id | frequency | degree |
+---------+---------+-----------+--------+
| 2331 | 29 | 2 | 1 |
| 2332 | 29 | 7 | 1 |
| 2333 | 29 | 4 | 1 |
| 2334 | 29 | 1 | 1 |
| 2335 | 29 | 1 | 1 |
| 2336 | 29 | 1 | 1 |
| 2337 | 29 | 2 | 1 |
| 2338 | 29 | 7 | 1 |
| 2343 | 29 | 1 | 3 |
| 2344 | 29 | 1 | 3 |
......
......
...... and so on.
Word_id points to Words present in other table and page_id points to URLs present in other table.
Now Suppose I want to search "Rapid 3D Prototyping Services". I brought the union of results corresponding to individual words by query ->
select * from words_detail where word_id=2353 or word_id=2364 or word_id=2709 or word_id=2710;
In above query the word_ids corresponds to the 4 words in the search query and the results are as below.
Union of page_id corresponding to individual words...
mysql>
select * from words_detail where word_id=2353 or word_id=2364 or word_id=2709 or word_id=2710;
+---------+---------+-----------+--------+
| word_id | page_id | frequency | degree |
+---------+---------+-----------+--------+
| 2353 | 29 | 2 | 4 |
| 2353 | 33 | 2 | 2 |
| 2353 | 36 | 5 | 9 |
| 2353 | 40 | 1 | 4 |
| 2353 | 41 | 1 | 9 |
| 2353 | 45 | 4 | 9 |
| 2353 | 47 | 2 | 9 |
| 2353 | 49 | 4 | 9 |
| 2353 | 52 | 1 | 4 |
| 2353 | 53 | 1 | 9 |
| 2353 | 66 | 2 | 9 |
| 2364 | 29 | 1 | 4 |
| 2364 | 34 | 1 | 4 |
| 2364 | 36 | 9 | 2 |
| 2709 | 36 | 1 | 9 |
| 2710 | 36 | 1 | 9 |
+---------+---------+-----------+--------+
16 rows in set (0.00 sec)
But I want the result to be sorted according to maximum match. The earlier result should be where all 4 words match, next result should be with 3 match and so on. In other words earlier results should have those page_id which are common to 4 word_ids, next should be those which are common in 3 words_ids and so on.
I checked here but this is not working in my case because in my case OR conditions are not matched in a single row.
How can such a query can be designed?
Use the occurence of you page_id as your matching count and then order by it.
select * from words_detail A
inner join
(SELECT PAGE_ID
, COUNT(PAGE_ID) matchCount
from words_detail
where word_id=2353 or word_id=2364 or word_id=2709 or word_id=2710
group by PAGE_ID) B
on A.PAGE_ID=B.PAGE_ID
where word_id=2353 or word_id=2364 or word_id=2709 or word_id=2710
order by matchCount desc
Try this
select p.*
from words_detail p
, (select word_id, count(1) as count
from words_detail where
word_id in (2353,2364,2709,2710) group by word_id) t
where p.word_id = t.word_id
order by t.count desc;
You can do a subquery to get the number of apperances for each page. Then you have to join the subquery with your table and you will be able to order the results by the number of page appearances.
Your final query should look like this:
SELECT *
FROM words_detail,
(
SELECT page_id,
COUNT(*) AS npages
FROM words_detail
WHERE word_id IN (2353, 2364, 2709, 2710)
GROUP BY page_id
) AS matches
WHERE words_detail.page_id = matches.page_id
AND word_id IN (2353, 2364, 2709, 2710)
ORDER BY matches.npages DESC