Currently I have 3 MySQL tables, one filed with the users information, one with their course history and the last one filled with their reward history.
I am attempting to create a "rewards" program if you will, using these two databases and a PHP script. As far as the reward requirements, I have 2 arrays setup for the two types of rewards:
//Pen Reward with course A & B required
$pen=array("a","b")
//Cup Reward with course B & C required
$cup=array("b","c")
I can't figure out how to first query for all user IDs, then go through their history. If they match the requirements set above, then to update the reward table to 1 (to show that they received the award)
UsersDB
userid name
----------------
1 bill
2 john
3 steve
HistoryDB
userid courseid
------------------
1 a
1 b
2 b
3 a
3 c
RewardHistoryDB
userid pen cup
---------------------
1 0 0
2 0 0
3 0 0
Ideally it after the PHP script runs, it would update the RewardHistoryDB to reflect that user 1 received a pen, and user 3 received a cup.(the DB would look like this:)
RewardHistoryDB (after)
userid pen cup
---------------------
1 1 0
2 0 0
3 0 1
Here is the PHP code I am using right now (not complete):
$userid=array();
$i=0;
//Find All users
$result = mysqli_query($con,"SELECT userid FROM usersdb")
while ($row = mysqli_fetch_array($result)){
$universityid[$i]=$row['universityid'];
$i++;
}
//Find History
$courseid=array();
foreach ($userid as $userid1){
$result = mysqli_query($con,"SELECT courseid FROM historydb WHERE userid='".$userid1."'");
while ($row = mysqli_fetch_array($result)){
$courseid[]=$row;
}
}
//Update Reward DB
//Don't even know where to start...
Any help would be greatly appreciated.
If you have any questions, please let me know.
Thank you in advanced!
http://sqlfiddle.com/#!2/1a96b/1/0
You can do this just as queries and without doing any logic in PHP
update RewardHistoryDB
set Pen = 1
where UserID in (
select UserID
from HistoryDB
where CourseID in ('A','B')
group by UserID
having count(UserID)=2);
update RewardHistoryDB
set Cup = 1
where UserID in (
select UserID
from HistoryDB
where CourseID in ('B','C')
group by UserID
having count(UserID)=2);
Or you can even do it in one, large statement...
update RewardHistoryDB
left outer join (
select UserID as Pens_UserID
from HistoryDB
where CourseID in ('A','B')
group by UserID
having count(UserID)=2 ) as Pens
on RewardHistoryDB.UserID = Pens.Pens_UserID
left outer join (
select UserID as Cups_UserID
from HistoryDB
where CourseID in ('B','C')
group by UserID
having count(UserID)=2 ) as Cups
on RewardHistoryDB.UserID = Cups.Cups_UserID
set Pen = case when Pens.Pens_UserID is not null then 1 else 0 end,
Cup = case when Cups.Cups_UserID is not null then 1 else 0 end
Related
I'm making a customer database application for a dancing school.
I need to display an overview of all customers that are participating in the same dancing level. But I want the overview order by couples not by the customer ID.
For this I'm joining three tables (look at the query below)
Each customer has a unique ID in the tabel CRM_CONTACTS and also has in it's row a reference to his or her partner (PARTNER_ID).
Table CRM_CONTACTS
ID CONTACTS_LNAME
1 VON KLOMPENBURG
2 Mc Donalds
3 MC Adams
4 Mr X
Then I have CRM_PRODUCTS
ID PRODUCTS_NAME
1 Beginners
2 intermediate
3 advanced
Then the table in which I assign a product/level to a contact and also indicate his/her partner
ID CONTACTS_ID PRODUCTS_ID PARTNER_ID
1 1 1 4
2 2 1 3
3 3 1 2
4 4 1 1
Now I would like to receive a list order by couple based on the parter_id
So for the beginners level I would get a list like this
1 VON KLOMPENBURG
2 Mr X
3 Mc Donalds
4 Mc Adams
Here's my select statement
$result = mysqli_query($coni,"SELECT CRM_PRODUCTS_PURCHASE.ID, CONTACTS_ID,
CRM_PRODUCTS.PRODUCTS_NAME,
CRM_PRODUCTS.PRODUCTS_PRICE,CRM_PRODUCTS_PURCHASE.PARTNER_ID,
CRM_PRODUCTS_PURCHASE.PARTNER_NAME,
PRODUCTS_PURCHASE_REMARKS,PRODUCTS_PURCHASE_DISCOUNT,
PRODUCTS_PURCHASE_PAIDBYBANK,PRODUCTS_PURCHASE_PAIDBYCASH,
CRM_CONTACTS.CONTACTS_LNAME, CRM_CONTACTS.CONTACTS_FNAME
FROM CRM_PRODUCTS_PURCHASE
LEFT JOIN CRM_CONTACTS ON CRM_PRODUCTS_PURCHASE.CONTACTS_ID = CRM_CONTACTS.ID
LEFT JOIN CRM_PRODUCTS ON CRM_PRODUCTS_PURCHASE.PRODUCTS_ID = CRM_PRODUCTS.ID
WHERE CRM_PRODUCTS_PURCHASE.PRODUCTS_ID = '". $PRODUCTS_ID . "'");
You can do something like this:
$result = mysqli_query($coni,"SELECT CRM_PRODUCTS_PURCHASE.ID, CONTACTS_ID,
CRM_PRODUCTS.PRODUCTS_NAME,
CRM_PRODUCTS.PRODUCTS_PRICE,CRM_PRODUCTS_PURCHASE.PARTNER_ID,
CRM_PRODUCTS_PURCHASE.PARTNER_NAME,
PRODUCTS_PURCHASE_REMARKS,PRODUCTS_PURCHASE_DISCOUNT,
PRODUCTS_PURCHASE_PAIDBYBANK,PRODUCTS_PURCHASE_PAIDBYCASH,
CRM_CONTACTS.CONTACTS_LNAME, CRM_CONTACTS.CONTACTS_FNAME
FROM CRM_PRODUCTS_PURCHASE
LEFT JOIN CRM_CONTACTS ON CRM_PRODUCTS_PURCHASE.CONTACTS_ID = CRM_CONTACTS.ID
LEFT JOIN CRM_PRODUCTS ON CRM_PRODUCTS_PURCHASE.PRODUCTS_ID = CRM_PRODUCTS.ID
WHERE CRM_PRODUCTS_PURCHASE.PRODUCTS_ID = '". $PRODUCTS_ID . "'
ORDER BY IF (ID < PARTNER_ID, ID, PARTNER_ID)");
And your customers will be ordered in couples.
I have a view where i need to get list of all dishes from menu table according to main_menuid for a particular user, But here i need to put some conditions
Currently i am using 3 tables for the entire process (table view for all 3 is given at the end)
1) main_menu
2) menu
3) cart
1) I need to get list of dishes according to main_menuid
so here if i need a list of dishes below MM1, so list of dishes that i should get from menu table is (main_menuid is the id of main_menu table)
id main_menuid dish
1 1 D1
2 1 D2
3 1 D3
code i used to get the above data is
$sql = "select * from menu where main_menuid = '".$mainmenuid."'";
$result = mysqli_query($con, $sql);
if (mysqli_num_rows($result) > 0)
{
while($row = mysqli_fetch_assoc($result))
{
print_r($row);
}
}
2) i will also have a userid with me so now i need to display the above list to a particular user (Let the userid be "1"), but if he already has added any of the above product to cart earlier then it's quanity should also get fetched from cart and for rest of the items(that are not added by him to the cart but is present in the above list) the quantity will be null, so the resulting view should be like this (menuid is the id of menu table)
id main_menuid menuid dish quantity userid
1 1 1 D1 3 1
2 1 1 D2 2 1
3 1 1 D3 0 1
code that i tried for the above result is (but it didn't gave me the desired result)
SELECT menu.main_menuid, menu.dish, cart.userid,
cart.quantity
FROM menu
LEFT JOIN cart ON menu.id=cart.menuid
WHERE main_menuid = '".$main_menuid."' and userid = '".$userid."'
Below is a sample view of all the tables that are being used in the above process
main menu
id mainmenu_name
1 MM1
2 MM2
3 MM3
4 MM4
menu
id main_menuid dish
1 1 D1
2 1 D2
3 1 D3
4 2 D4
5 3 D5
6 4 D6
cart
id userid menuid dish main_menuid quantity
1 1 1 D1 1 3
2 1 2 D2 1 2
3 2 1 D1 1 3
can anyone please tell how to achieve the desired result (DBMS: mysql)
move userID to the join as it is eliminating the null values generated from the left join.
SELECT menu.main_menuid, menu.menuid, menu.dish, cart.userid,
cart.quantity
FROM menu
LEFT JOIN cart ON menu.id=cart.menuid
and userid = '".$userid."'
WHERE main_menuid = '".$main_menuid."'
However this implies you want some dishes not associated to the user so userID will be NULL in some cases.
Why does this work and not in the where clause? Because the filter is applied BEFORE the join. This allows the null values which would occur as a result of the left join to remain.
You can't get userid from your cart table directly, if the desired menu item is not in cart. So your WHERE clause filters out these records. Try this request:
SELECT menu.main_menuid, menu.menuid, menu.dish, IF(ISNULL(cart.userid), ".$main_menuid.", cart.userid) AS userid,
IF(ISNULL(cart.quantity), 0, cart.quantity) AS quantity
FROM menu
LEFT JOIN cart ON menu.id=cart.menuid
WHERE menu.main_menuid = '".$main_menuid."'
I think the problem is on the LEFT JOIN. You should do this way:
LEFT JOIN cart ON menu.id=cart.menuid and cart.dish = menu.dish
EDIT
When you do this way, the userid column will be null at the last line, to avoid this, on select you should put something like this:
SELECT menu.main_menuid, menu.dish,
COALESCE(cart.quantity, 0), -- will put 0 when null
COALESCE(cart.userid, '".$userid."') as userid -- will put '".$userid."' when null
Music table
id | title
1 Rap God
2 Blank Space
3 Bad Blood
4 Speedom
5 Hit 'em up
Like table
u_id | m_id
1 1
1 2
1 4
1 5
2 3
2 4
2 5
3 1
3 5
4 1
4 2
4 5
Now if someone visits music with m_id = 1
Then the output might be like
m_id
5
2
4
To explain this a bit...
As m_id = 1 is liked by users -> {1,3,4} which in turn likes ->{2,4,5} musics. Since m_id=5 is liked by max number of users its first followed by m_id = 2 and m_id = 4.
My Try
I queried the users who liked m_id = 1
SELECT u_id FROM likes WHERE m_id =1
Then i stored in in an array and selected each of their likes and
arranged them in desc order of count.
But it is a very slow and long process is there any way i can do this ?
p.s I have heard of Association Rules and Bayesian theorem can be user to achieve this. But can anyone help me out with an example ?
You can JOIN back on the Like table and do something like this.
SELECT also_like.m_id, COUNT(also_like.m_id)
FROM [like] AS did_like
JOIN [like] AS also_like ON
also_like.u_id = did_like.u_id
AND also_like.m_id != did_like.m_id
WHERE did_like.m_id = 1
GROUP BY also_like.m_id
ORDER BY COUNT(also_like.m_id)
Essentially you are getting a list of users who liked an item then getting a complete list of those user's likes excluding the item they just liked.
You can then add a HAVING clause or LIMIT to filter things down a bit more.
using a subquery ...
SELECT m_id, count(u_id) as Rank FROM `like`
WHERE u_id in
(
SELECT u_id
FROM `like`
WHERE m_id = 1
)
AND m_id <> 1
GROUP BY m_id
ORDER BY Rank DESC
and optionally
LIMIT 0, 10
or how many "alsolikes" you want to display
I need a small hint... I've got 2 Tables.
Table 1 gets data from an external api.
Table 2 is static.
Table 1: data
id name status ratio import_id
1 Test online 3 1
2 Tee online 2 1
3 Test online 1 2
4 Tee online 0.01 2
5 Test offline 4 3
6 Teee online 3 3
7 Teet online 1 3
Table 2: names
id name tag active
1 Test t1 1
2 Tee t2 1
3 Teee t3 0
4 Teet t4 1
I want to have the ID from the table names (to write into another table and execute a cronjob)
Explanation Table 1:
id - AI
name - just the name
status - if the entry is active
ratio - the main select
import_id - every 10 minutes I do import from json (~40 entries)
what i've got:
$result = mysql_query("
SELECT
import_id
FROM
data
ORDER BY id DESC LIMIT 1");
while($raw = mysql_fetch_object($result))
{
$the_id = $raw->import_id;
echo $the_id;
}
Now I've got the ID and try to get the latest entry (import_id) with the highest ratio:
$c_result = mysql_query("
SELECT
name, active, ratio, import_id
FROM
data
WHERE
active = '1' AND import_id = '$the_id'
ORDER BY
ratio DESC LIMIT 1");
while($chosen = mysql_fetch_object($c_result))
{
$the_c = $chosen->name;
echo $the_c;
}
That works flawless.
But it is possible that one of the 40 entries provided by api is not in my table "names" or it is not marked as "active".
But I only want the names.id of
the name with the highest ratio
which is in my table "names"
which is marked as active in "names"
and the data.status is online
which is from the latest import (highest import_id)
and write it to another table.
I thought about a LEFT JOIN but if the names.name is not in the table "names" i just get an empty result.
Have you got a hint in the right direction?
SELECT d.name, active, ratio, import_id
FROM data d
JOIN names n ON d.name = n.name
WHERE import_id = (SELECT import_id
FROM data
ORDER BY id DESC
LIMIT 1)
AND d.status = 'online'
AND n.active = 1
ORDER BY ratio DESC
LIMIT 1
DEMO
I have 2 tables colorcode & users
colorcode
ID colorid colorname
------------------------
1 1 yellow
2 2 black
3 3 red
4 4 white
users
ID userid colorid
------------------------
1 1 1,2
2 2 3,4
3 3 1,3,4
4 4 1
How do I retrieve & query individual colorid
$aa = $db->query("SELECT * FROM colorcode");
$colors = array();
while ($colordata = mysql_fetch_assoc($aa)) {
$colors[] = $colordata["colorid"];
}
Let's say I want query which users have yellow color & what it's the statement should I use for users
SELECT .. FROM users
WHERE colorid ....
It's a bad design... since you're trying to access the individual color_ids in the user table, but have stored them as a comma-separated list, you canot have the database do a normal join for you - you've killed off the main point of using a relational database by making it impossible to for the database to do the relating for you.
However, since you're on mysql, you're in luck - mysql has a function for cases like this:
SELECT users.ID, userid, GROUP_CONCAT(colorcode.colorname)
FROM users
LEFT JOIN colorcode ON FIND_IN_SET(colorcode.ID, users.colorid)
GROUP BY users.id
SELECT * FROM users
WHERE colorid LIKE "%1%"
But what I would really do is make a link table from users to colors:
usersToColors:
ID userid colorid
------------------------
1 1 1
2 1 2
3 2 3
4 2 4
...
Then you could do:
SELECT * FROM users u, usersToColors utc
WHERE u.userid = utc.userid
AND utc.colorid = 1;
Or even:
SELECT * FROM users u, usersToColors utc, colors c
WHERE u.userid = utc.userid
AND utc.colorid = c.colorid
AND c.colorname = "yellow";