Loop in a form of sql query - mysql

I don't know where to start so I will just post an example what I need:
A B
5 0
10 0
15 0
20 0
25* 1*
30 0
35 1
40 1
45* 0
50 0
55 0
60 0
65 0
70 1
75 1
80 0
85 0
I need a query that will look for 1 in column B (first row found in 25 1),"entry point" from this point, go down and look for first column A, that is 20 more than a A in the start point - "exit point" (found row 45 0), return row index of "entry point" and "exit point" , in this case 25 1 and 45 0 rows.
Also, the tricky part might be, that I don't want row 35 1 or 40 1, it also contains 1 in B column, but I don't want rows in between entry and exit points, so the next applicable row will be row 70 1 as an entry point (75 1 also to be)
This is something I would be able to do in java loop without problem, but I am getting lower performance than I would like, so it's been suggested using db for this kind of operation should be faster. Is it possible to do such db query?

If i understand corectly that you need the first valid entry point and its first valid exit point, something like this should do the job
SELECT
(
SELECT
MIN(A)
FROM
table
WHERE
B = 1
) entry,
A exit,
FROM
table
WHERE
A + 20 >= (SELECT
MIN(A)
FROM
table
WHERE
B = 1)
AND
B = 0
LIMIT 1

Related

It is possible in mysql query to dynamically sum row based on column with criteria?

So, its my original table. The duration is in second.
Duration
Status
30
0
30
0
31
1
30
1
31
1
31
0
31
1
30
0
30
0
30
0
31
0
30
1
30
1
30
0
and i want the result is something like this (if possible)
Status
sum of duration
0
60
1
92
0
31
1
31
0
121
1
60
0
30
i want to sum the duration for each status (0 and 1), i have try some query like sum, group, or where modification... but i dont get the correct one.
I hope someone can help me. Thank you in advance : )
note :
+ i use mysql phpmyadmin
++ im sorry, i just edited the result that i desire. because there is slight mistake in my manual count
Remember that an RDBMS table is a set.
What you're showing in your question looks like
an ordered list, rather than a set.
Write some code that reads
duration, status, and writes
duration, status, session_id.
Now, with those seven distinct IDs appearing in a table,
you're in a good position to use SUM(duration)
in a GROUP BY session_id query.

mysql pick up a random entry selected from certain criterial

I want sort one user from table who never had a note different from 0
then update the record,
then insert a new row
user note
12 1
23 0
88 0
45 0
12 0
23 0
12 0
88 2
sort a user except user 12 and user 88 becouse the have already a note somewhere
somethink like
SELECT * FROM table WHERE note=0 ORDER BY rand() LIMIT 1
the problem is that i've many users duplicate so i dont know how to exlude that...
let's say that i randomly choose the user 23
the table should become
user note
12 1
23 0
88 0
45 0
12 0
23 X <--- mark the random user choosen
12 0
88 2
23 0 <--- add a new line
in the next random pick up only the number 45 will be avaiable becouse other user has somewhere a note != 0
for this last request i've to do 2 query UPDATE then INSERT or i can do with just one query?
You can avoid subqueries for improved performance and go like this:
SELECT *
FROM YourTable
GROUP BY name
HAVING SUM(note)=0 ORDER BY rand() LIMIT 1;
Here is an SQL Fiddle DEMO.
You can use nested select :
SELECT * FROM table WHERE note=0 and user not in (select user from table where note>0) ORDER BY rand() LIMIT 1
however u should really use primary unique index on users

SQL Server - Calculate current row value using previous row value

I have following table and using SQL Server 2008
Tbl_TRNSACTION
RowNum Transaction Type InQty OutQty InPrice
1 IN 20 0 20
2 IN 50 0 40
3 OUT 0 10 -
4 IN 10 0 30
I expect output in following format
If TransType is IN,
then (InQty*InPrice) is added in CumulativeStockVal
and StockRate = (CumulativeStockVal / Balance).
If Transaction Type is OUT,
then (OutQty*previous(StockRate)) is subtracted from CumulativeStockVal.
RowNum TransType InQty OutQty Balance CumulatveStockVal StockRate
1 IN 20 0 20 400 20
2 IN 50 0 70 2400 34.285
3 OUT 0 10 60 2057.15 34.285
4 IN 10 0 70 2357.15 33.673
Please reply.Thanks.
Try using Window Offset Functions combining with AGGREGATE functions.
EDIT: I found you a tut where it is shown very clearly, watch from minute 15.
https://www.microsoftvirtualacademy.com/en-US/training-courses/querying-microsoft-sql-server-2012-databases-jump-start-8241?l=OZmttuJy_2304984382

Simple Line Graph in SSRS

I'm having issues using the line chart control in SSRS. If I was in excel this would be easy but for some reason I can't wrap my head around how to do it in SSRS
I'm returning 5 rows of data from a database and need to chart 3 of the rows.
Name J F M A M J J A S
1 Requested 13 19 4 20 2 0 0 0 0
2 Completed 1 0 0 4 1 0 0 0 0
3 % Completed .7 0 0 0.2 0.5 0 0 0 0
4 Monthly Ba 12 19 4 16 1 0 0 0 0
5 YTD Backlog 12 31 35 51 52 52 52 52 52
The rows consist of the name and the value for that month.
I'm trying to display a chart for rows 1, 2, and 5 that would look like a normal line graph with each of the Months being on the horizontal column and the value being the data point.
However, when I start adding things to my chart I'm getting 36 different series, one for each Month for each series and nothing seems to be working right. It's also splitting into Group 1 and 2 at the bottom which makes no sense to me. I feel like I'm missing something simple, most likely a grouping of some kind.
EDIT:
I ended up taking Nathan's suggestion and added an unpivot on the table to rotate the data into an acceptable format for SSRS
Thanks
Can you alter the query that is returning the results for the dataset?
If so try changing it so that the dataset looks more like this:
monthnumber month Requested Completed YTD Backlog
1 J 13 1 12
2 F 19 0 31
3 M 4 0 35
4 A 20 4 51
etc.
You should be able to add "Requested", "Completed" and "YTD Backlog" as Values and "month" as a Category to produce the chart you want.
I added a "monthnumber" column, as you will probably want something like this so that you can set the category (month) sorting expression to this, otherwise they will appear in alphabetical order.

mySQL to retrieve records that repeat a value in order

I have a big table with 300,000 records. This table has a integer value called "velocity" and it`s value is from 0 to 100.
In the firsts records, the value is 0 and I want to remove. I want to remove from the query, the records where the velocity field repeats more than 10 times. For example:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 5 10 12 13 15 20 30 20 15 10 8 5 2 1 0 0 0 0 4 5 10 20...
[-------remove this-----------].......................................................................[---------] <- do not remove this
Thanks
The easiest way to do this is with a loop.
You can write a stored procedure that iterates through the records, or you might do it outside of the database. I'd do it like that if this needs to be done once. If this is a continuous process, it's better to make sure that the extra data is just not inserted into the database in the first place.
Anyway, if you insist on doing this in pure SQL, without stored procedures with loops, you can use a query like this:
set #groupnum=0;
select
GroupNum,
count(*) as RecsInGroup
from
(
select
t1.id as Id,
t1.velocity as velocity1,
t2.velocity as velocity2,
if(t1.velocity<>t2.velocity,#groupnum:=#groupnum+1,#groupnum) as GroupNum
from
VelocityTable as t1
join
VelocityTable as t2
on
t1.id=t2.id-1
) as groups
group by
GroupNum
having RecsInGroup>10
What happens here?
Step 1
The inner query just selects all records in your table, but splits the data in sequential groups.
So, using your example, it does this:
velocity : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 5 10 12 13 15 20 30 20 15 10 8 5 2 1 0 0 0 0 4 5 10 20
Groupnum : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 18 18 18 19 20 21 22
It does that by joining the table to itself, by linking subsequent records in the table. Every time the left and right velocity are different, the GroupNum is increased. Otherwise it's left unchanged.
Step 2
The result if the query is wrapped in an outer query, and grouped by GroupNum. Again, using your example it would result in this:
GroupNum,RecsInGroup
0,15 // !!
1,1
2,1
3,1
4,1
5,1
6,1
7,1
8,1
9,1
10,1
11,1
12,1
13,1
14,1
15,1
16,1
17,1
18,4 // !!
19,1
20,1
21,1
By Adding the having RecsInGroup>10 clause, the result becomes this:
GroupNum,RecsInGroup
0,15
Now, with this list of GroupNum's you can delete records.
Step 3
With the query above you have:
A list of all your records, with an added GroupNum column.
The list of GroupNum's that need to be removed.
Deleting the records should be easy at this point.
I'd just rip through the records sequentially, with a variable sized window that expands and contracts to comprehend identical values. Whenever the size is >= 10 when the value changes, delete the rows using the primary keys.
You can put BEGIN TRAN and COMMIT TRAN at the beginning and end of the DELETE statements to make things reasonably efficient.
thank you very much. I'm allmost there, but i tried it with a mySQL View as table source and it's not working (unkown table xxx). I can't use the whole table because it's have more than 19 millions records, I just need the record from a specific day, vehicle plate and city.