Looking for close value to zero for a particular id - mysql

I'm looking for the nearest value to zero for a particular id
My input is
tech_Id time_diff
1000 100
1000 200
1000 -50
1000 -10
1001 100
1001 200
1001 50
1001 10
1002 -50
1002 -10
1003 130
1003 -140
1003 -2
expected output
tech_Id time_diff
1000 -10
1001 10
1002 -10
1003 -2
thanks in advance

You can find min of absolute value of time diff.
select t1.*
from your_table t1
join (
select tech_id, min(abs(time_diff)) as time_diff
from your_table
group by tech_id
) t2 on t1.tech_id = t2.tech_id and abs(t1.time_diff) = t2.time_diff;

Related

how to display Each record 4 for each id column

id serviceid name cost date
201 15 X 50 25.12.2016
201 15 Y 55 29.11.2016
201 120 Z 50 27.11.2016
201 19 w 50 22 .11.2016
201 158 p 50 23.11.2016
201 18 q 50 21.11.2016
201 16 rs 50 24.11.2016
201 81 rs 50 2.11.2016
202 18 X 50 25.12.2016
202 18 Y 55 29.11.2016
202 15 Z 50 27.11.2016
202 19 w 50 22 .11.2016
203 15 p 50 23.11.2016
203 18 q 50 21.11.2016
203 16 rs 50 24.11.2016
0 81 rs 50 2.11.2016
Desire Output :
id serviceid name cost date
201 15 X 50 25.12.2016
201 15 Y 55 29.11.2016
201 120 Z 50 27.11.2016
201 16 rs 50 24.11.2016
202 18 X 50 25.12.2016
202 18 Y 55 29.11.2016
202 15 Z 50 27.11.2016
202 19 w 50 22 .11.2016
203 15 p 50 23.11.2016
203 18 q 50 21.11.2016
203 16 rs 50 24.11.2016
0 81 rs 50 2.11.2016
i want to display each record 4 - 4 record service for each id i am trying to apply using self Join but there is Problem coming please tell or suggest me how to ac-chive for this.
SELECT a.*
FROM mytable AS a
WHERE
(SELECT COUNT(*) FROM mytable AS b
WHERE b.id = a.id and b.serviceid >= a.serviceid) <= 4
ORDER BY a.id , a.date
this query am trying but i am unable to fetch it for each id there should top 4 service id based on date.
To make your desired result, I think you should use mysql variable like this:
select
t1.*
from mytable t1
join (
select
`id`,
`serviceid`,
`name`,
`cost`,
`date`,
#rowno := case when #grp = `id` then #rowno + 1 else 1 end as rowno,
#grp := `id`
from mytable
cross join (select #rowno:=0, #grp:=null) v
order by `id`, `date` desc) t2
on t1.id = t2.id
and t1.`date` = t2.`date`
and t2.rowno < 5
and this seems to be a classic top x record in each group issue, take a look of How to select the first/least/max row per group in SQL

how do i join two different tables in mysql

This is table1:
id name m1 m2 m3 total itemno
1 raj 10 10 10 30 1
2 ram 60 60 60 180 1
3 kumar 70 70 70 210 1
4 kanna 50 50 50 150 1
5 vivek 64 64 91 200 1
5 vivek 90 90 90 270 2
This is table2:
id name mark1 mark2 mark3 itemno
101 vivek 78 78 78 1
102 vivekkanna 89 88 78 1
103 rajagopalan 97 90 98 1
104 kumar 69 54 56 1
101 vivek 90 90 90 2
I want to join these two tables like this into a result set that looks like this:
id name m1 m2 m3 total mark1 mark2 mark3 item no
1 raj 10 10 10 30 0 0 0 1
2 ram 60 60 60 180 0 0 0 1
3 kumar 70 70 70 210 69 54 56 1
4 kanna 50 50 50 150 0 0 0 1
5 vivek 64 64 91 200 78 78 78 1
5 vivek 90 90 90 270 90 90 90 2
Seems you want a regular LEFT JOIN, returning a default value if the row in table2 does not exist;
SELECT t1.id, t1.name, t1.m1, t1.m2, t1.m3,
COALESCE(t2.mark1, 0) mark1, COALESCE(t2.mark2, 0) mark2, t1.itemno
FROM table1 t1
LEFT JOIN table2 t2 ON t1.name = t2.name AND t1.itemno = t2.itemno
ORDER BY t1.id, t1.itemno
An SQLfiddle to test with
We use a LEFT JOIN to get the default NULL value for all table2 fields that don't match with a row in table1, then COALESCE to turn them into 0 instead.

mysql several column ranking per group

I have table data in this format
studno name level year term subject1 subject2 subject3
212 victor l1 2000 1 45 56 80
213 HOM l1 2000 1 42 56 70
214 ken l1 2000 1 60 70 50
215 ted l1 2000 1 46 36 47
212 victor l1 2000 2 45 36 68
213 Hom l1 2000 2 38 78 49
214 ken l1 2000 2 38 34 62
my desired output is the following
studno name level year term subject1 sub1rank subject2 sub2rank
213 victor l1 2000 1 42 3 56 2
214 HOM l1 2000 1 60 1 70 1
215 TED l1 2000 1 46 2 36 3
212 victor l1 2000 2 45 2 36 1
213 hOM l1 2000 2 38 3 36 1
214 KEN l1 2000 2 38 3 32 3
215 TED l1 2000 2 90 1 30 4
I have managed to get the rank but the problem is how to get the rank per year, level, term and subject. another problem is that if i use nested statement and try to create view in mysql database it throws an error, "View's SELECT contains a subquery in the FROM clause"
You can do this with correlated subqueries in the select clause. If I understand correctly, something like this:
select t.*,
(select COUNT(distinct t1.subject1)
from t t2
where t2.level = t.level and t2.year = t.year and t2.term = t.term and
t2.subject1 >= t.subject1
) as subj1rank,
(select COUNT(distinct t2.subject2)
from t t2
where t2.level = t.level and t2.year = t.year and t2.term = t.term and
t2.subject2 >= t.subject2
) as subj2rank
from t
The count(*) might be count(distinct subject1) (etc.), depending on how you treat ties.

Scalar function taking so much time

I need someone who can tell me what I'm missing.
I have this scalar function in SQL Server 2008:
ALTER function [dbo].[SKU](#id1 int, #id2 int)
returns int
begin
return (
SELECT SUM(Value)
FROM Table
where id_1 = #id1
and id_2 = #id2)
end
And the table is like this:
id_1 id_2 Value
1004 1 10
1004 1 30
1004 2 100
1005 1 90
1005 1 5
1005 1 5
If I execute:
select [dbo].[SKU](1004,1)
it returns 40 - That's ok
select [dbo].[SKU](1004,2)
returns 100 - OK
select [dbo].[SKU](1005,1)
returns 100 - OK
At this point all seems ok, but my table has almost a millon rows... the result of SKU goes to the same table (update part).
But I ran it for two hours now, and is still running...
My question: I've never seen such as long time consuming query. It's ok? I'm missing something?
Thanks!, and happy new year ! D:
If changing the table design or programming to it is not an option, an easy solution would be to create a covering index on the fields you are using in your function.
Something like
CREATE INDEX IX_TABLE_ID_1_ID_2_VALUE ON dbo.Table (id_1, id_2) INCLUDE (Value)
This is not to be interpreted as an answer but an attempt to drill down to the real problem
Currently, this is as how I interpretate the actions that get executed
Starting from the initial table
id_1 id_2 Value Result
1004 1 10 NULL
1004 1 30 NULL
1004 2 100 NULL
1005 1 90 NULL
1005 1 5 NULL
1005 1 5 NULL
After update table set result = dbo.SKU(1004, 2) this would become
id_1 id_2 Value Result
1004 1 10 40
1004 1 30 40
1004 2 100 40
1005 1 90 40
1005 1 5 40
1005 1 5 40
After update table set result = dbo.SKU(1004, 1) this would become
id_1 id_2 Value Result
1004 1 10 100
1004 1 30 100
1004 2 100 100
1005 1 90 100
1005 1 5 100
1005 1 5 100
After update table set result = dbo.SKU(1005, 1) this would become (remain)
id_1 id_2 Value Result
1004 1 10 100
1004 1 30 100
1004 2 100 100
1005 1 90 100
1005 1 5 100
1005 1 5 100
and somehow after that, the result is divided by id_2
id_1 id_2 Value Result
1004 1 10 100
1004 1 30 100
1004 2 100 50
1005 1 90 100
1005 1 5 100
1005 1 5 100
Clearly, my interpretation and what really happens don't match (at least I hope so).
This might get you what you need a little quicker if you don't have to use a function.
;with sumVal
as
(
select t1.id_1, t1.id_2, SUM(t1.value) [result]
from [table] t1
group by t1.id_1, t1.id_2
)
select t2.*, s.result
from sumVal s
left join [table] t2 on s.id_1 = t2.id_1 and s.id_2 = t2.id_2
It ran in less than 5 seconds on over 800,000 rows on my test.

count amount for sub code

tab1
id code name
1001 0 palani
1002 1001 shanker
1003 1002 raghu
1004 1003 kabhir
1005 1003 vani
1006 1002 priya
tab2
id code name amount tax
1 1002 b 100 1
2 1002 j 20 10
3 1003 jk 23 20
4 1004 jk 675 9
5 1005 o 67 3
6 1003 u 122 4
7 1003 o 98 1
8 1003 iu 98 1
9 1002 po 4 0.4
10 1005 pl 1 0.1
12 1005 tf 1 0.1
24 1006 e 23 2.3
id 1001 see code 1001 corresponding id 1002
id 1002 see code 1002 corresponding id 1003,1006
id 1003 see code 1003 corresponding id 1004,1005
others no need
Result need like this
code amount tax
1001 124 11.4
1002 364 28.3
1003 744 12.2
Please send the mysql query for this
GROUP BY is your friend:
select tab1.id, sum (tab2.amount) amount, sum (tab2.tax) tax
from
tab1, tab2
where tab1.code = tab2.id
and tab1.id in (1001, 1002, 1003)
group by tab1.id
This will get what you want from tab2
SELECT code, SUM(amount), SUM(tax) FROM tab GROUP BY code ORDER BY code
I can't see how tab1 fits into what you want
does it work (not tested)
select SUM(t2.amount) AS Amount,SUM(t2.tax) AS totalTax,t2.code FROM
table2 t2
INNER JOIN table1 t1 ON t1.code=t2.code