Between Math and Sql Query - mysql

please help me to answer this question..
if I have database, table name is table1 and the field name is example its contain 5 numbers like this:
example
1
2
3
4
5
then I would like do this with database above:
1*2 = 2
3*2 = 6
4*6 = 24
5*24 = 120
120 * 10% = 12
What is the correct sql query to make that happen?
thank you very much

You can use user-defined variables in you query ,if multiplication result exceeds from 100 and you need to divide it by 10 you can do so
SELECT
CONCAT(example,'*',#mul) `expression`,
#mul := CASE
WHEN #mul* example >100
THEN (#mul* example/10)
ELSE #mul* example END
mul
FROM Table1,
(SELECT #mul:=1) p
ORDER BY `example`
Fiddle Demo
For your exactly the same desired result set this would work
SELECT * FROM
(SELECT
CONCAT(example,'*',#mul) `expression`,
#mul := #mul* example mul
FROM Table1,
(SELECT #mul:=1) p
ORDER BY `example`
) t
UNION
SELECT CONCAT(#mul,'*',' 10% ') `expression`,
(#mul/10) FROM (SELECT #mul) p1
Fiddle Demo

Related

query select max with mixed string and int

I have a table which contain a column for generated code, the data type is VARCHAR with mixed string/int values like :
Table demo
ID code
==============
1 | 001qwe
2 | 002qwe
3 | 001asd
Question :
1. How to get max value that contain qwe or asd, i want it used as filter.
2. How to get id of row which contain the maxed value
i want something like :
select *,MAX(SUBSTRING(code, 1, 3)) from demo where SUBSTRING(code, 4, 3) = 'asd'
Yes this case code length is 6 and number is 3 digit in the beginning of data
Considering above you can write your query as below
select *,left(`code`,3)
from demo
order by left(`code`,3) * 1 desc
limit 1
DEMO
to get individual results you can use following
SELECT a.id qweid, a.code qwecode,b.id asdid,b.code asdcode
FROM
(SELECT id,`code`
FROM demo
WHERE RIGHT(`code`,3) = 'qwe'
ORDER BY LEFT(`code`,3) * 1 DESC
LIMIT 1) a
CROSS JOIN(SELECT id,`code`
FROM demo
WHERE RIGHT(`code`,3) = 'asd'
ORDER BY LEFT(`code`,3) * 1 DESC
LIMIT 1) b
DEMO

SQL Query, how to select a interval where the next value is current value +1, identifying the next gap and leave everything else untouched?

I'm making a program on java using sql querys and i'd like to update a sequence of ids adding 1 to each, but only in the sequence interval.
Let's say i have a table like this:
1 - a | 2 - b | 3 - c | 5 - e | 6 - f
And i'd like to "push" a's ID and subsequents forward by 1, but only while the difference between one another is still 1. The result would be like this:
2 - a | 3 - b | 4 - c | 5 - e | 6 - f
I know it is possible to do programatically, but is there a way to do this with SQL querys? If not, what would be the best way to do this?
Thanks in advance.
Edit: Found the answer thanks to Thorsten Kettner, my query ended up like this:
update pair set id = id + 1
where id >= 1
and id <
(
select min(id)
from (select * from pair) as gap
where gap.id > 1 and not exists
(
select *
from (select * from pair) as oneless
where oneless.id = gap.id - 1
)
)
order by id desc
If you know where the gap is that you want closed (ID 4 in your case) use this:
update mytable set id = id + 1 where id < 4;
If you don't know where the gap is, find it:
select min(id) - 1
from mytable
where not exists
(
select *
from mytable oneless
where oneless.id = mytable.id - 1
);
We can combine both statments now to do the update:
update mytable set id = id + 1
where id <
(
select min(id) - 1
from mytable
where not exists
(
select *
from mytable oneless
where oneless.id = mytable.id - 1
)
);
Let's call your table Pair and the two columns Key and Value. Your query would be something like this:
update p1
set Key = p1.Key + 1
from Pair as p1
inner join Pair as p2
on p2.Key = p1.Key + 1
PS. I'm assuming your result has a typo because after the update, f should have a value of 7.

Count first occurence with column value ordered by another column

I have an assigns table with the following columns:
id - int
id_lead - int
id_source - int
date_assigned - int (this represents a unix timestamp)
Now, lets say I have the following data in this table:
id id_lead id_source date_assigned
1 20 5 1462544612
2 20 6 1462544624
3 22 6 1462544615
4 22 5 1462544626
5 22 7 1462544632
6 25 6 1462544614
7 25 8 1462544621
Now, lets say I want to get a count of the rows whose id_source is 6, and is the first entry for each lead (sorted by date_assigned asc).
So in this case, the count would = 2, because there are 2 leads (id_lead 22 and 25) whose first id_source is 6.
How would I write this query so that it is fast and would work fine as a subquery select? I was thinking something like this which doesn't work:
select count(*) from `assigns` where `id_source`=6 order by `date_assigned` asc limit 1
I have no idea how to write this query in an optimal way. Any help would be appreciated.
Pseudocode:
select rows
with a.id_source = 6
but only if
there do not exist any row
with same id_lead
and smaller date_assigned
Translate it to SQL
select * -- select rows
from assigns a
where a.id_source = 6 -- with a.id_source = 6
and not exists ( -- but only if there do not exist any row
select 1
from assigns a1
where a1.id_lead = a.id_lead -- with same id_lead
and a1.date_assigned < a.date_assigned -- and smaller date_assigned
)
Now replace select * with select count(*) and you'll get your result.
http://sqlfiddle.com/#!9/3dc0f5/7
Update:
The NOT-EXIST query can be rewritten to an excluding LEFT JOIN query:
select count(*)
from assigns a
left join assigns a1
on a1.id_lead = a.id_lead
and a1.date_assigned < a.date_assigned
where a.id_source = 6
and a1.id_lead is null
If you want to get the count for all values of id_source, the folowing query might be the fastest:
select a.id_source, count(1)
from (
select a1.id_lead, min(a1.date_assigned) date_assigned
from assigns a1
group by a1.id_lead
) a1
join assigns a
on a.id_lead = a1.id_lead
and a.date_assigned = a1.date_assigned
group by a.id_source
You still can replace group by a.id_source with where a.id_source = 6.
The queries need indexes on assigns(id_source) and assigns(id_lead, date_assigned).
Simple query for that would be
check here http://sqlfiddle.com/#!9/8666e0/7
select count(*) from
(select * from assigns group by id_lead )t
where t.id_source=6

selecting multiple max values

i have a table like this on a mysql database:
id | item
-----------
1 | 2
2 | 2
3 | 4
4 | 5
5 | 8
6 | 8
7 | 8
i want the result to be 3 record with the highest Item value
select max(item) returns only 1 value
how can i select multiple max values?
thank you
You can use a derived table to get the maximum value and join it back to the original table to see all rows corresponding to it.
select t.id, t.item
from tablename t
join (select max(item) as mxitem from tablename) x
on x.mxitem = t.item
Edit:
select t.co_travelers_id, t.booking_id, t.accounts_id
from a_co_travelers t
join (select accounts_id, max(booking_id) as mxitem
from a_co_travelers
group by accounts_id) x
on x.mxitem = t.booking_id and t.accounts_id = x.accounts_id
If you use an 'aggregate function' without GROUP BY only one row will be returned.
You may use GROUP BY , with aggregate functions.
Here is SQLFiddle Demo
SELECT id,max(item) AS item
FROM table_name
GROUP BY id
ORDER BY item DESC
LIMIT 3
Hope this helps.
There is the graphical explanation.
There is script mysql (low abstraction level, no inner join or sth)
select * from ocena, uczen where ocena.ocena = (SELECT MAX(ocena.ocena) FROM ocena WHERE ocena.przedmiot_id="4" and ocena.uczen_id="1") and ocena.uczen_id=uczen.id and ocena.przedmiot_id="4" and uczen_id="1"

row dependant variables in mysql query

I have a mysql database as follows. I am using it with phpmyadmin.
id time_came time_exit
0 2 3
1 3 5
5 5 1
7 1 10
9 1 8
I want another column as "wait" with the following logic,
foreach(i in time_came){
wait=count(time_came<i&&i<time_exit)
}
So then each column has a "wait" value too. I can do this with php. But I need to do this with mysql. I am confusing because "i" is varying for each row?
Thanks in advance.
Is this what you want?
select t.*,
(select count(*)
from table t2
where t2.time_came between t.time_came and t2.time_came < t.time_exit
) as wait
from table t;
EDIT:
To do the update, you need to use join:
update table t join
(select t.id,
(select count(*)
from table t2
where t2.time_came between t.time_came and t2.time_came < t.time_exit
) as wait
from table t
) as newval
on t.id = newval.id
set t.wait = newval.wait