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.
Related
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`
i have two tables. 'listing_messages' and 'listing_message_history'.
listing_messages
=============
message_id listing_id listing_user third_party_user
1 162 7 32
2 162 7 33
3 162 7 12
listing_message_history
======================
listing_message_history message_id is_checked
1 1 0
2 1 1
3 1 1
4 2 0
5 2 1
6 3 0
Search criteria==> listing_user=7, is_checked=1
I want result..
message_id count_of_unread_message_history
12
2 1
3 0
I have made a query is
SELECT count(`lmh`.`message_history_id`) AS COUNT,
`lmh`.`message_id`
FROM `listing_message_history` AS `lmh`
LEFT JOIN `listing_messages` AS `lm` ON `lmh`.`message_id` = `lm`.`message_id`
WHERE `lm`.`third_party_user`=7
AND `lmh`.is_checked=1
GROUP BY `lm`.`message_id`
but it does not returns message_id with count = 0 which message_id do not have is_checked=1
In general, when you use left join, filter conditions on the second table should go in the on clause not the where clause. Try this:
SELECT count(`lmh`.`message_history_id`) AS COUNT,
`lmh`.`message_id`
FROM `listing_message_history` `lmh` LEFT JOIN
`listing_messages` `lm`
ON `lmh`.`message_id` = `lm`.`message_id` AND
`lm`.`third_party_user` = 7
WHERE `lmh`.is_checked = 1
GROUP BY `lmh`.`message_id`;
In addition, you should use the first table for the group by, not the second table.
This question already has an answer here:
UPDATE all column values equivalent to another tables column value based on their id
(1 answer)
Closed 8 years ago.
i have two tables
fw_invitations
id moduleid qdetailid
1 1 10
2 2 11
3 3 12
4 7 13
5 8 14
fw_ind_details
id moduleid officeid
10 0 100
11 0 110
12 0 120
13 0 130
14 0 104
the column qdetaild is the primary key in fw_ind_details.what i want to do is want to take the moduleid from fw_invitations table for that particular qdetailid and want to update in fw_ind_details.that is it should be done with an update query.
desired output
fw_ind_details
id moduleid officeid
10 1 100
11 2 110
12 3 120
13 7 130
14 8 104
this is what i tried so far;
UPDATE `fw_ind_details`
SET `moduleid`=(select moduleid
from fw_invitaions fo,fw_ind_details fi
where f0.qdetailid=fi.id
)
i know my approach is wrong,any suggestion will be appreciated.
I am open for the use of PHP.
UPDATE fw_ind_details d
JOIN fw_invitations i ON i.qdetailid = d.id
SET d.moduleid = i.moduleid
To get a particular module ID when there are multiple matches, you can join with a subquery; this example uses the highest module ID:
UPDATE fw_ind_details d
JOIN (SELECT qdetailid, MAX(moduleid) moduleid
FROM fw_invitations
GROUP BY qdetailid) i
ON i.qdetailid = d.id
SET d.moduleid = i.moduleid
Use a join...
UPDATE `fw_ind_details`
JOIN fw_invitations ON fw_ind_details.id = fw_invitations.qdetailid
SET fw_ind_details.moduleid = fw_invitations.moduleid
The SQL to use is:
UPDATE `fw_ind_details` fi
SET `moduleid`=(SELECT moduleid
FROM fw_invitaions fo
WHERE fo. qdetailid =fi.id
)
I have a table with some values inserted on a daily basis, something like this
-----------
id | count
-----------
1 | 97
2 | **97**
3 | 59
4 | 62
5 | 47
6 | 59
7 | 59
8 | **97**
-----------
I need to get the max day difference between repeated values, i.e, as you can see the 1st and 2nd value is 97, that is 1 day difference, but the next occurrence of 97 is 6 days later, so I need to get this "Max" difference (6).
same thing for 59, the max day difference is 3 days (3) -- between day 3 and 6.
At this moment I`m using php arrays like this Example:
$q = " SELECT id FROM table WHERE VALUE = 97 ";
// etc ... the array looks like this
$array = {1, 2, 8};
then I get the "Max" difference, but I just want to know if there is any way to do this in mysql, thanks
EDIT:
//if we list only the column "count":
44 5 *97* 74 5 **97** 7 3 2 31 9 8 4 2 1 **97** 4 7 7 8 *97*
step1 : "97" is in 3rd position, then in 6th position (diff = 3)
step2 : "97" is in 6th position, then in 16th position (diff = 10)
step3 : "97" is in 16th position, then in 21st position (diff = 5)
step4 : MAX diff = 10
I must complain about this, I posted this question at 08:59 AM, I reloaded the page 1 minute later (At 9:00) and it was already down-voted, there was no time to read and understand the question, this is absurd
Both work:
http://sqlfiddle.com/#!2/243f2/22
select a.blahday ad, max(b.blahday) bd, a.blahday - max(b.blahday) diff from blah a join blah b using (blahcount)
where blahcount = 97
and a.blahday > b.blahday
group by ad
order by diff desc
limit 1
http://sqlfiddle.com/#!2/243f2/25
select a.blahday ab,
(select max(blahday) from blah where blahcount = a.blahcount and blahday < a.blahday) bd
from blah a
where blahcount = 97
order by ab - bd desc
limit 1
Try this:
select
(`a`.`max_id` - `b`.`min_id`) as `max_day_diff`, `a`.`count`
from
(select max(id) as `max_id`, `count`
from `table` group by `count`
) a
inner join
(select min(id) as `min_id`, `count`
from `table` group by `count`
) b
on `a`.`count` = `b`.`count`
This is the fiddle:
http://sqlfiddle.com/#!2/1a6a3/10
This will give max_day_diff as 0 for rows with only one count value (like 62, 47 in your case)
I think this will get you what you're looking for.
SQLFiddle!
That's a pretty funky table you've got there, btw.
The table fields and its data:
auto_id user_id file_id
1 1 1
2 1 13
3 1 14
4 4 1
5 5 1
6 8 18
7 8 51
8 8 31
And what I want is:
userFiles[user_id] = 'file_id';
E.g:
userFiles[1] = '1,13,14';
userFiles[4] = '1';
userFiles[5] = '1';
userFiles[8] = '18,51,31';
Thank you very much!!
SELECT user_id, GROUP_CONCAT(file_id)
FROM yourtable
GROUP BY user_id
is the easy way to do it, if there aren't too many records - group_concat has a length limit of 1024 bytes (default, but is configurable).
The SQL query you can use is straightforward for each ID:
"select file_id from TABLE where user_id = " . $user_id;
Load your answers into an array, then:
$string = implode(",",$answers);
Put the whole thing in a for loop around your user_id and assign to your userFiles array.