sql query multiple table query issue - php

I've a following 3 table in mysql db.
project table :
p_id p_name p_notes is_active p_owner p_owner_id p_date
8 project notes 1 shibbir 18 01-01-2015
Project_assign_clients:
pac_id assign_clients assign_client_id is_main_user p_id
39 Hara Adachi 8725 1 8
40 Aihara 8726 0 8
41 Akanuma Kenji 8023 0 8
42 Bayani Patrick 7801 0 8
Project_assign_users:
pas_id assign_users assign_user_id p_id
5 teustace 12 8
6 alawson 10 8
7 mfischer 14 8
8 smitchell 15 8
Now I want to get how many projects users created. e.g. I have logged in user who's id is 18 so using above table it's should be return 1 project using mysqli_num_rows. here is my query but it's return 30 strange !!
$logged_user_id = $_SESSION['user_id'];
$query = mysqli_query($link, "SELECT projects . *, projects_assign_clients . *, projects_assign_users . * FROM projects LEFT JOIN projects_assign_clients on projects.p_id = projects_assign_clients.p_id LEFT JOIN projects_assign_users ON projects.p_id = projects_assign_users.p_id WHERE projects.p_owner_id = '$logged_user_id' ");
$num = mysqli_num_rows($query);
echo $num . " found"; // retrun 30 but should be 1 according to above table data

Just keep your query, but also add a sub-select to get the number of projects:
SELECT projects.*,
projects_assign_clients.*,
projects_assign_users.*,
(select count(*) from projects where p_owner_id = p.p_owner_id)
FROM projects p LEFT JOIN projects_assign_clients
ON projects.p_id = projects_assign_clients.p_id
LEFT JOIN projects_assign_users ON projects.p_id = projects_assign_users.p_id
WHERE projects.p_owner_id = '$logged_user_id'

Related

Looking for MySQL/MariaDB where query over muliple rows

Table Products
ad_id| property_id | property_value_id
69 4 1
69 7 6
69 6 3
67 7 6
...
For Example:
I need to search ((where property_id = 4 and property_value_id = 1) and (where property_id = 7 and property_value_id = 6))
Result should be: 69
The values im searching for are dynamic.
SELECT DISTINCT ad_id
FROM
(SELECT ad_id
FROM Producst
WHERE (property_id = 4 AND property_value_id = 1)
OR (property_id = 7 AND property_value_id = 6)
OR (property_id = 6 AND property_value_id = 3)
group by ad_id
having count(ad_id) = 3) as subquery
Should do the job.
You can join the table with itself three times, one for each pair of searched value. The query can take the form:
select distinct a.ad_id
from my_table a
join my_table b on b.ad_id = a.ad_id
join my_table c on c.ad_id = a.ad_id
where a.property_id = 4 and a.property_value_id = 1
or b.property_id = 7 and b.property_value_id = 6
or c.property_id = 6 and c.property_value_id = 3

count id, insert, then update by number range in another columns in same table mysql

I am trying to update levels in db like this:
"count (id) from users table where referral_id = id As aggref set agg_referral = aggref AND level = 1 if aggref in between 1 to 3"
So far i know but no success :(
Here is my db structure
users table:
id (AI) name Referral id agg_referral Level
=========== ========== ================== ============== ======
1 user A 0 0 0
2 user B 3 0 0
3 user C 1 0 0
4 user D 3 0 0
Here is my code i am running it using cron job:
<?php
include( $_SERVER['DOCUMENT_ROOT'] . '/config.php' );
mysql_connect(DB_HOST,DB_USER,DB_PASS);
mysql_select_db(DB_NAME);
$query="UPDATE users SET agg_referral = (SELECT COUNT(id) from users WHERE users.referral_id = users.id)";
mysql_query($query);
?>
I am expecting results like this
id (AI) name Referral id agg_referral Level
=========== ========== ================== ============== ======
1 user A 0 0 0
2 user B 3 0 0
3 user C 1 2 1
4 user D 3 0 0
You can use an update join:
update users u1
join (
select referral_id,
count(*) cnt
from users
group by referral_id
) u2 on u1.id = u2.referral_id
set u1.agg_referral = u2.cnt,
u1.level = case
when cnt < 1
then 0
else ceil((- 5 + sqrt(25 + 8 * cnt)) / 2)
end;
Demo
It finds times an id is referred and then join it with the table to update the counts and level.
The case statement produces 0 for cnt = 0 or less, 1 for cnt between 1 and 3, 2 for cnt between 4 and 7 and . . so on.
To learn more on how the formula works, see https://math.stackexchange.com/questions/2171745/find-group-number-for-a-given-number-from-groups-of-increasing-size
EDIT:
If your initial group size is value other than 3, use this to get the required equation:
ceil((1 - 2 * g + sqrt(4 * g * g + 1 - 4 * g + 8 * cnt)) / 2)
where g is the intial size of the group.
For g = 3, it solves to:
ceil( -5 + sqrt(25 + 8 * cnt) / 2 )
for g = 10, it solves to:
ceil( -19 + sqrt(361 + 8 * cnt) / 2 )
On how this function is made, see the link provided above.
In MySQL, you can do this by counting the number of referrals for each id using a subquery. Then use that information in the update:
UPDATE users u JOIN
(SELECT referral_id, COUNT(*) as cnt
FROM users u
GROUP BY referral_id
) ur
ON u.id = ur.referral_id
SET u.agg_referral = ur.cnt,
u.level = (CASE WHEN ur.cnt BETWEEN 1 and 3 THEN 2 ELSE level END);

Mysql Where Column A = X and Column B = Y and or Column B = Z

I'm trying to get a set of values from a pivot table where column A is equal to an array of values, so for example ID 12 has attribute_value_id equal to 3 and 9. Can this be done? I've got this far...
ID | post_id | attribute_id | attribute_value_id
8 12 1 3
9 12 2 13
10 13 1 3
11 13 2 9
12 16 1 3
13 16 2 9
88 11 1 1
89 11 2 8
90 11 3 18
91 11 4 22
The query...
select *
from `searching_for_posts`
where (
select count(*)
from `attributes`
inner join `searching_for_attributes`
on `attributes`.`id` = `searching_for_attributes`.`attribute_id`
where `searching_for_attributes`.`searching_for_post_id` = `searching_for_posts`.`id`
and (`attribute_value_id` = 3 and `attribute_value_id` = 9)
) >= 1
If I use the and then I get no values. If I use the or then I get 3 values but it should return 2. I have limited SQL experience.
You can do this using group by and having. Your logic is hard to follow, but it is something like this:
select post_id
from table t
where attribute_value_id in (3, 9)
group by post_id
having count(distinct attribute_id) = 2;
I would think you would want to check on attribute_id as well, but that doesn't seem to be part of the question.
EDIT:
If these are stored in another table:
select a.post_id
from attributes a join
searching_for_attributes sfa
on a.attribute_id = sfa.attribute_id and
a.attribute_value_id = sfa.attribute_value_id
group by a.post_id
having count(*) = (select count(*) from searching_for_attributes);
In response to #GordonLinoff answer, I've managed to use GROUP BY and HAVING COUNT to get the desired data. Here's what I came up with and hope this helps someone else...
select *
from `searching_for_posts`
where (
select count(*)
from `attributes`
inner join `searching_for_attributes` on `attributes`.`id` = `searching_for_attributes`.`attribute_id`
where `searching_for_attributes`.`searching_for_post_id` = `searching_for_posts`.`id`
and `attribute_value_id` in (3, 9)
having count(distinct `attributes`.`id`) = 2
) >= 1
group by `id`

how to select records based on count of column field

I have a scenario that a query who will work like select records based on status = 1 with highly number of records found in database.
suppose i want to select artists who have max number of status = 1 with their names fetch from other table.
another problem is my query is repetiting records.
my query:
SELECT order.status,
order.artist_id,
web_user.uFname,
web_user.uLname,
web_user.uID
FROM `order`
INNER JOIN `web_user`
ON web_user.uID = order.artist_id
HAVING order.status = '1'
my record set i am getting:
status artistid uFname uLaname uID
1 14 Pitbull Armando 14
1 14 Pitbull Armando 14
1 13 Enrique Iglesias 13
1 15 Robyn Rihanna 15
1 15 Robyn Rihanna 15
1 15 Robyn Rihanna 15
i simple want:
downloadtimes artistid uFname uLaname uID
2 14 Pitbull Armando 14
1 13 Enrique Iglesias 13
3 15 Robyn Rihanna 15
please enhanced my query.
You can use COUNT()
SELECT
COUNT(*) AS downloadtimes ,
order.artist_id,
web_user.uFname,
web_user.uLname,
web_user.uID
FROM `order`
INNER JOIN `web_user` ON web_user.uID = order.artist_id
WHERE order.status = '1'
GROUP BY order.artist_id
you should use the count
like:
COUNT(*) AS downloadtimes
you should just add the like you full code:
SELECT
COUNT(*) AS downloadtimes ,
order.artist_id,
web_user.uFname,
web_user.uLname,
web_user.uID
FROM `order`
INNER JOIN `web_user` ON web_user.uID = order.artist_id
WHERE order.status = '1'
GROUP BY order.artist_id
and refer this following link:
SQL COUNT

Autopopulating a Mysql Table from Another Mysql Table with iterations through PHP

The explanation of this may seem a bit long and convoluted but please bear with me. In essence what I want to do is fill a mysql table(A) from another mysql table(B) in my database but in order to do so I need to duplicate values in table (A) so that there will be enough entries to accomodate for the values in table B.
Now for a more concrete example
How the tables look
course_details table
course_details_id | course_id | year_id | teacher_id
+------------------+-----------+-----------+------------+
1 1 To be Set 36
2 2 To be Set 54
3 3 To be Set 78
4 4 To be Set 23
year table
year_semester_id | year | semester
+-----------------+------+---------+
1 2012 1
2 2012 2
3 2012 3
4 2012 4
5 2013 1
6 2013 2
7 2013 3
8 2013 4
How I want the table to look
course_details_id | course_id | year_id | teacher_id
-------------------+-----------+---------+------------+
1 1 1 36
2 1 2 36
3 1 3 36
4 1 4 36
5 1 5 36
6 1 6 58
7 1 7 36
8 1 8 47
9 2 1 54
10 2 2 54
11 2 3 54
12 2 4 67
13 2 5 67
14 2 6 54
15 2 7 54
16 2 8 54
How the code looks
<?php
require_once('open_db.php');
get_dbhandle();
$query_year = "SELECT * FROM year";
$result_year = mysql_query($query_year) or die(mysql_error());
$num_year_rows = mysql_num_rows($result_year);
$num_year_rows = ($num_year_rows - 1);
$query_yearid = "SELECT year_semester_id FROM year";
$result_yearid = mysql_query($query_yearid) or die(mysql_error());
$result_ccheck = mysql_query("SELECT course_id FROM courses");
while($row = mysql_fetch_array($result_ccheck))
{
$course_id = $row['course_id'];
for($i = $num_year_rows; $i >= 0; $i--)
{
$query_cdetails = "INSERT INTO course_details (course_id) VALUES ('$course_id')";
$result_cdetails = mysql_query($query_cdetails);
while($row = mysql_fetch_array($result_yearid))
{
$year_semester_id = $row['year_semester_id'];
$query = "INSERT INTO course_details(year_semester_id) SELECT year_semester_id FROM year";
$result = mysql_query($query);
}
}
}
?>
What it does vs what I want it to do: As it currently is set, it correctly creates duplicates of each course_id in course_details table to match the number of year_semester_id's which exist in the years table which is perfect. The problem comes to inserting the year_semester_id's in each corresponding table slot of the table course_details.
In other words, to ensure that when course_id =1 , year_semester_id=1, course_id=1, year_semester_id =2,....course_id=1, year_semester_id=8, course_id=2, year_semester_id=1, course_id=2, year_semester_id=2......course_id=2, year semester_id =8, course_id=3, year_semester_id =1 etc and so on.... Therein lies the issue.
A recap of how the code works, it counts the number of year_semester_id's in the years table, it then subtracts that number by 1 which is the amount of times the course_id is currently in the course_details table and it duplicates it by that number. This total number (the duplicates) plus the original course_id should be the total amount of year_semester_ids. I now want to insert every year_semester_id for every course_id that exists and loop through until each course_id is accounted for. Thank you
This is what im talking about check the code iy you have a trouble understanding, let me know.
It looks to me like what you're attempting to do could easily be done without bloating your database by taking advantage of relational tables. In this case, if I'm understanding you correctly, the end result here is you want to have duplicates of all the rows from course_details with the empty column set to each of the rows from the year table.
That being true, you could select that data using JOIN statements:
SELECT `a`.`course_id` , `b`.`year_semester_id` as `year_id` , `a`.`teacher_id` FROM `course_details` `a` INNER JOIN `year` `b`
That should return the data you want in a MySQL resultset. If you want to insert that data into a table, just make sure the table has the correct columns, and set the course_Details_id field to auto increment and do:
INSERT INTO `tablename` ( `course_id` , `year_semester_id` , `year_id` ) VALUES (
SELECT `a`.`course_details_id` , `a`.`course_id` , `b`.`year_semester_id` as `year_id` , `a`.`teacher_id` FROM `course_details` `a` INNER JOIN `year` `b`
)
This should insert all the data you need into the new MySQL table without the need for PHP scripts.

Categories