Mysql: divide result by column change - mysql

I have a table like these
date - name - val
16/02 - Rossi - 5
16/02 - Zingaro - 8
18/02 - Beniamino - 4
18/02 - Bosso - 2
Is possible with a query to get result like this?
16/02
Rossi - 5
Zingaro - 8
18/02
Beniamino - 4
Bosso - 2
Or I must do the query and then work with if/else ?

Simple select query can be like
select name,val froom table where date=&date
so with this you will get all the record with name & val for particular date.
Now question is no one is going to write query for each date.
So simply you can fetch all distinct date from your table with query
select DISTINCT date from table name
Now what remains is that you need to write a procedure which will have a loop and will take output of ditinct date as iterator and for each iteration fire select query for name & val.

Related

Minus the value based on data using MySQL

I've the following data.
What I need like below
I need to minus order by 1 with 2.
Example : (1-2) and I've display the result in order by 3.
If the branch having order_by as 1 - display as it is.
Using MySQL, how can I get this result?
You can get this result with a UNION query. The first part selects all rows from your table, the second uses a self-join to find branches which have order_by values of both 1 and 2, and subtracts their due values to get the new due value:
SELECT *
FROM data
UNION ALL
SELECT 3, d1.branch, d1.due - d2.due
FROM data d1
JOIN data d2 ON d2.branch = d1.branch AND d2.order_by = 2
WHERE d1.order_by = 1
ORDER BY branch, order_by
Demo on dbfiddle

Recursively running a MySQL function

I have a function in MySQL that needs to be run about 50 times (not a set value) in a query. the inputs are currently stored in an array such as
[1,2,3,4,5,6,7,8,9,10]
when executing the MySQL query individually it's working fine, please see below
column_name denotes the column it's getting the data for, in this case, it's a DOUBLE in the database
The second value in the MOD() function is the input I'm supplying MySQL from the aforementioned array
SELECT id, MOD(column_name, 4) AS mod_output
FROM table
HAVING mod_output > 10
To achieve the output I require* the following code works
SELECT id, MOD(column_name, 4) AS mod_output1, MOD(column_name, 5) AS mod_output2, MOD(column_name, 6) AS mod_output3
FROM table
HAVING mod_output1 > 10 AND mod_output2 > 10 AND mod_output3 > 10
However this obviously is extremely dirty, and when having not 3 inputs, but over 50, this will become highly inefficient.
Appart from calling over 50 individual querys, is there a better way to acchieve the same sort (see below) of output?
In escennce i need to supply MySQL with a list of values and have it run MOD() over all of them on a specified column.
The only data I need returned is the id's of the rows that match the MOD() functions output with the specified input (see value 2 of the MOD() function) where the output is less than 10
Please note, MOD() has been used as an example function, however, the final function required *should* be a drop in replacement
example table layout
id | column_name
1 | 0.234977
2 | 0.957739
3 | 2.499387
4 | 48.395777
5 | 9.943782
6 | -39.234894
7 | 23.49859
.....
(The title may be worded wrong, I'm not quite sure how else you'd explain what I'm trying to do here)
Use a join and derived table or temporary table:
SELECT n.n, t.id, MOD(t.column_name, n.n) AS mod_output
FROM table t CROSS JOIN
(SELECT 4 as n UNION ALL SELECT 5 UNION ALL SELECT 6 . . .
) n
WHERE MOD(t.column_name, n.n) > 10;
If you want the results as columns, you can use conditional aggregation afterwards.

Converting mysql query to mssql query for sql server 2000

I was stuck figuring out why there's error when I execute the mysql query on mssql query. I was using sql server 2000. My goal is to achieve the result with the same way that I use on mysql.
A little explanation about the database: The database is about a gps tracker with 3 main table: incoming, md_login, and master_device.
Here is the table and the structure that I will give:
Structure of table incoming:
This table mainly used for the incoming data of the gps tracker for each vehicle, so every interval there'll be incoming data into this tables. Regarding about some of the table structure, you can say 'tanggal' is the meaning of 'date' in English
Text1 varchar
...
Text18 varchar <used as imei>
...
Text31 varchar
Distance varchar
Tanggal datetime
TanggalIncoming datetime
StartDate datetime
EndDate datetime
EngineStatus varchar
AccStatus varchar
Moving varchar
Address varchar
Structure of table md_login:
This table used to store the vehicle with the imei data, so 1 Log_ID can have many Log_DeviceID.
Log_ID char <used as username>
Log_DeviceID varchar <used as vehicle number>
Log_DeviceIMEI varchar <used as imei>
Log_Date datetime
Sample data of table md_login:
Log_ID - Alex
Log_DeviceID - B 7777 GHI
Log_DeviceImei - 012896001194123
Log_Date - 2017-05-30 13:46:57
Structure of table master_device:
Device_Imei varchar
Device_PoliceNumber char
Device_MobileNumber char
Device_MobileNumber2 char
Model varchar
Port char
PortDevice char
ActiveDate datetime
LastUpdate datetime
IdxConn varchar
CommandOperate char
Picture varchar
Sample data of table master_device:
Device_Imei - 012896001194123
Device_PoliceNumber - B 7777 GHI
Device_MobileNumber - 01234567
Device_MobileNumber2 -
Model - STV-08
Port - 340
PortDevice - 20557
ActiveDate - 2017-05-30 13:46:57
LastUpdate - Null
IdxConn - Null
CommandOperate - Null
Picture - livina_grey.png
Here's the query that already works on mysql:
SELECT fi.text18 as Imei,
md.Device_PoliceNumber,
fi.Text6 as Lat,
fi.Text8 as Lng,
fi.Text10 as Speed,
fi.Text16 as Gps_Signal,
fi.Text21 as Battery,
fi.Text22 as Charging,
fi.Text29 as Oil,
fi.Text30 as Temperature,
md.Picture,
fi.EngineStatus,
fi.TanggalIncoming,
fi.Moving,
fi.Address
FROM incoming fi
INNER JOIN (SELECT MAX(tanggalincoming) as maxtglincoming,text18,moving
FROM incoming
GROUP BY text18) ri
ON ri.maxtglincoming = fi.tanggalincoming AND
ri.text18=fi.text18
INNER JOIN md_login AS mdl ON (ri.text18=mdl.log_deviceimei AND
mdl.log_id='alex')
INNER JOIN master_device AS md ON md.device_imei=mdl.log_deviceimei
GROUP BY fi.text18
ORDER BY md.Device_PoliceNumber ASC
A little explanation about the query:
So I was using MAX(tanggalincoming) at first to get the row result based on the latest update from table call incoming. the next step is: I was doing the inner join from the latest incoming table with the full incoming table so the data that will return is based from the latest incoming data that already inner joined.
And here is the sample data result that will be shown when I execute the query in mysql. There can be result more than 1 row data since 1 username can have more than 1 vehicle.
Imei - 012896001194123
Device_PoliceNumber - B 7777 GHI
Lat - -6.27585
Lng - 106.66172
Speed 0
Gps_Signal F
Battery - F:4.18V
Charging - 1
Oil - Null
Temperature - Null
Picture - livina_grey.png
EngineStatus - OFF
TanggalIncoming - 2017-05-31 05:25:59
Moving - STOP
Address - Example Street
But when I try to execute the query on sql server 2000, there's the error showing like this:
Server: Msg 8120, Level 16, State 1, Line 1. Column 'md.Device_PoliceNumber' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
So the main question is: How can I achieve the same result in the sql query?
If you use aggregate functions (like MAX, SUM etc) in Sql Server, you should include all other fields in GROUP BY clause.
In this case in your sub-query you have SELECT MAX(tanggalincoming) as maxtglincoming,text18,moving but only text18 is included into GROUP BY.
Should look like this:
SELECT MAX(tanggalincoming) as maxtglincoming,text18,moving
FROM incoming
GROUP BY text18,moving
The second is you don't have any aggregate functions in the big query. So you should remove it.
If you used GROUP BY to suppress duplications, use DISTINCT instead

Find number of items left based upon credit's id and all ids prior

I have a t variable which contains 100 and one table .
that table name credit and it contains the following data
Id
1
2
3
I would like the result set to look like this:
result
99 (100 - 1)
97 (100 - 2 - 1)
94 (100 - 3 - 2 - 1)
So far, I have been able to use the following code successfully:
set #t=100;
select #t:=#t-id as result from credit;
Is there a way to do this without using a variable?
This is quite simple and you shouldn't have to use the variable at all:
SELECT 100-(SELECT SUM(c2.id) FROM credit c2 WHERE c2.id <= c.id)
FROM credit c;
Here is a SQL Fiddle for you:
http://sqlfiddle.com/#!9/1fc3c6/6
The subquery simply gets the sum of all numbers including, and prior to the credit id.

Replace last string in IP-address accornding to specific condition in PL/SQL

I've got table with fields and values:
ENTADDR (VARCHAR2) ENTIFINDEX (VARCHAR2)
18.17.16.2 1
18.17.16.53 2
18.17.16.1 3
18.17.16.54 4
I have to join 1st and 3rd record knowing 1st ENTADDR.
So how can I get 18.17.16.1 from 18.17.16.2? (last char -1). Similarly I have to join 2nd and 4th record knowing 2nd ENTADDR (18.17.16.54 from 18.17.16.53, i.e last char +1)
So I need "select" like:
Select
ENTIFINDEX from table1
where 'some transformation of ENTADDR (changing last char) '= ENTADDR
Thanks in advice!!
Is this what you are looking at
SQL> select concat (substr('18.17.16.2',1,9),substr ('18.17.16.2',-1)-1 ) as "concat val" from dual;
concat val
----------
18.17.16.1
select concat(left(ENTADDR,locate('.',ENTADDR,locate('.',ENTADDR,locate('.',ENTADDR)+1)+1)),right(ENTADDR,length(ENTADDR)-locate('.',ENTADDR,locate('.',ENTADDR,locate('.',ENTADDR)+1)+1))-ENTIFINDEX) as ipminusone from table
That searches for first second and third '.' and then subtracts the value of ENTIFINDEX from the last portion of the IP
You could also do this with a stored procedure if you're planning on doing this fairly often.