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.
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 would like order the result of my select ids starting with 16, 15 and 17.
How could I do this?
My Select:
SELECT id_t_produtos
FROM table
ORDER BY nullif(id_t_produtos, 16) ASC
The expected response:
- 16
- 15
- 17
- 1
- 2
- 3 ...
If I understand well, I would do something like this
select ids from table
order by
case ids when 16 then 0
when 15 then 1
when 17 then 2
else 3
end,
ids
replace ids by id_t_produtos if that's the ordering field, not really clear...
SELECT ids
FROM table
ORDER BY CASE id_t_produtos
WHEN 16 THEN 1
WHEN 15 THEN 2
WHEN 17 THEN 3
WHEN 1 THEN 4
WHEN 2 THEN 5
WHEN 3 THEN 6
ELSE 7 END ASC, id_t_produtos ASC
MySQL
I have table, where i store user_matches and it result:
n_match id_user id_score
1 55 1
1 66 0
This mean, 'user with id=55 win match with id=1 to user with id=66'.
So, we have 10, 100, 1000 matches, where user win or lose to opponents:
n_match id_user id_score
1 55 1 (win)
1 66 0
2 55 0 (lose)
2 77 1
3 55 1 (win)
3 77 0
4 55 1 (win)
4 77 0
5 55 1 (win)
5 77 0
Ok. As u can see, user win 3 matches without losing (win series)- and that's what i need from my query.
Question: How could i get from this table the longest series of won matches? Is it possible without looping on sql side or server side- just from query?
Thx.
Edit: One of solution i just now understand,- to get all matches as string like 001010101111010101011, then split it into array of strings with separator '0' -> [1, 1, 1, 1111, ...] and just take the longest string length.
But in this case i have to write server side code =\ That's not good, but mb the fastest.
The best way to do this is to calculate the cumulative number of losses for any match. For a sequence of wins, this value is constant. You can then use group by to get the length of the longest such sequence.
This version of the query is database-neutral. It uses subqueries to get the counts:
select user_id, max(NumWinsInRow)
from (select user_id, cumlosses, count(*)-1 as NumWinsInRow
from (select m.*,
(select sum(case when id_score = 0 then 1 else 0 end) from user_matches m2 where m2.id_user = m.id_user and m2.n_match <= m.n_match
) as CumLosses
from user_matches m
) t
group by cumlosses, user_id
) t
group by user_id
This query should run faster if you have an index on user_matches(id_user, n_math, id_score).
What I want to do is to select a value of the database,
Lets say:
id ---- giftid ---- userid
1 1 481
2 1 422
3 7 123
4 9 542
5 1 122
6 1 455
For example, there are 4 users that want to have the same giftid:
1, 2, 5, 6
It means that each one will have 25% to be chosen.
How can I make the "percent selection"?
Assuming every userid can only claim a giftid once, you can use the ORDER BY RAND() in MySQL. This will firstly select all the rows from table table where the giftid is 1 and then the results are ordered randomly. The LIMIT 1 ensures that only the first record is returned
SELECT * FROM table
WHERE giftid = `1`
ORDER BY RAND()
LIMIT 1
Are you looking this?
SELECT giftid, 1.0 / COUNT(*) percentSelection
FROM tableName
GROUP BY giftid
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.