Summing in mysql previous row with current - mysql

Need help to make query.
I have table like this:
kli, akt, mes
'2', '2', '201209'
'2', '2', '201210'
'3', '3', '201211'
And I need a result table:
kli, akt, mes
'2', '2', '201209'
'4', '4', '201210'
'7', '7', '201211'
result tables sum by field mes, current and all previous rows

try the below query
SELECT SUM(b.kli),SUM(b.akt),a.mes FROM tableName a INNER JOIN tableName b ON a.mes >= b.mes GROUP BY a.mes

Related

how to reorder row position using select statement in mysql

SELECT * FROM TJU.`group`;
group_id, name
'1', 'x'
'2', 'y'
'3', 'z'
'4', 'a'
'5', 'b'
I want re arrange position of data in mysql using select statement
expect output
group_id, name
'1', 'x'
'2', 'y'
'3', 'z'
'5', 'b'
'4', 'a'
please suggest me how to implement this so that I can get record like this
try a query like this:
select * from TJU.`group` order by FIELD(group_id,1,2,3,5,4(;;
to change id without name
select
find_in_set (id,'1,2,3,5,4'),`name`
from TJU.`group`

SQL nested select sum returns wrong integer

I have the following select statement:
SELECT
T.name,
C.name as competence_name,
THC.competence_level_id as requiredLevel,
(SELECT SUM(UHC.competence_level_id) FROM user_has_competence UHC INNER JOIN user U ON U.id = UHC.user_id WHERE competence_id = C.id AND U.title_id = T.id GROUP BY T.id) as current_level,
(SELECT
ROUND(SUM(UHC.competence_level_id)/ COUNT(UHC.user_id))
FROM
user_has_competence UHC
JOIN user U ON U.id = UHC.user_id
WHERE
competence_id = C.id
AND U.title_id = T.id GROUP BY T.id) - THC.competence_level_id as gap,
C.id
FROM
title_has_competence THC
JOIN
title T ON T.id = THC.title_id
JOIN
competence C ON C.id = THC.competence_id
This returns the following result:
'Head of IT', 'Office', '7', '16', '1', '524'
'Head of IT', 'Empatisk', '2', '5', '1', '527'
'Head of IT', 'Målrettet', '5', '12', '1', '529'
'Head of IT', 'Udadvendt', '10', NULL, NULL, '525'
'Webudvikler', 'Office', '2', '3', '1', '524'
'Webudvikler', 'Outlook', '3', '4', '1', '526'
'Webudvikler', 'Målrettet', '6', '10', '4', '529'
'Webudvikler', 'Back-end', '9', '9', '0', '534'
'Webudvikler', 'Infosoft', '10', '5', '-5', '532'
However the result is invalid:
In the first row you will see the current level sum is = 16 this should be 9 (6 + 3)
The gap is also incorrect as the gap should be 9 / 2 = 4.5 - 7 = -2.5
So my question is what am i doing wrong? why is my SUM() function returning way to much.
Also note that the COUNT() returns the right value = 2
The Tables
title_has_competence
id title_id competence_id competence_level_id
'82', '165', '527', '2'
'85', '166', '524', '2'
'86', '166', '526', '3'
'83', '165', '529', '5'
'87', '166', '529', '6'
'81', '165', '524', '7'
'88', '166', '534', '9'
'84', '165', '525', '10'
'89', '166', '532', '10'
User_has_competence
user_id, competence_id, competence_level_id, progression
'1', '524', '6', '0'
'1', '527', '4', '0'
'1', '529', '3', '0'
'2', '524', '10', '0'
'2', '527', '1', '0'
'2', '529', '9', '0'
'3', '524', '3', '0'
'3', '526', '4', '0'
'3', '529', '10', '0'
'3', '532', '5', '0'
'3', '534', '9', '0'
title
id, name organization_id
'165', 'Head of IT', '1'
'166', 'Webudvikler', '1'
User
id, username, password, title_id,
1 ** , ** , 165
2 ** , ** , 165
3 ** , ** , 166

Use nested subquery to fetch value with multiple condition

I have a table named test_plan (id, unit, num)
I inserted some values
INSERT INTO `test_plan` (`id`, `unit`, `num`) VALUES
('1', '1', '12'),
('2', '1', '13'),
('3', '1', '14'),
('4', '1', '10'),
('5', '2', '10'),
('6', '2', '9'),
('7', '2', '-1'),
('8', '2', '-1'),
('9', '2', '-1'),
('10', '3', '-1'),
('11', '3', '-1'),
('12', '3', '-1');
I have to fetch unit what is fraction of each unit to total unit when num is not equals to -1
i.e.after run the query it display as unit 1 is 100% completed, unit 2 is 40% completed, unit 3 is 0% completed as row wise. I can count the number of each unit but not the how much it completed.
I tried JOIN for this
SELECT a.unit, numb / count(*) as frac FROM test_plan as a
LEFT OUTER JOIN (SELECT unit, count(num) as numb FROM test_plan where num != -1 group by unit) as b
ON a.unit = b.unit group by a.unit;
try this:
select unit,
(sum(case when num = -1 then 0 else 1 end) / count(*)) * 100 as pct_complete
from lecture_plan group by unit;
there's no need for a nested sub query, the combination of aggregation and the case statement is sufficient

SQL query to show top x records with evenly distributed values

I have a database of contacts at companies. Multiple contacts per company in different departments. Each company has turnover and industry data attached to it.
I need to write a query that shows the top 10 most recently added contacts (unix timestamp) but i don't want it to be all Marketing contacts (even if the top 10 are), i would like to look at the top 100 instead and get 10 contacts out that are from different departments. So instead of the top 10 being all marketing, there might be 2 marketing, 2 I.T, 2 HR, 2 Personnel.
So my query basically is this:
SELECT DISTINCT `surname`, `job_title`, `company_name`
FROM (`company_database`)
WHERE `employee_code` IN ('6', '7', '8', '9', '10', '11', '12', '13')
AND `turnover_code` IN ('5', '6', '7', '8')
AND `contact_code` IN ('16', '17', '26', '27', '9', '10', '30', '31', '23', '24', '12', '13') AND `industry_code` NOT IN ('22', '17', '35', '36') LIMIT 10
But that simply returns a unique row. What i need is one contact per company and no more than 1 contact_code type. I also only want 10 rows returned, but obviously to get this 1 per contact code per row, the query will need to look at more than 10.
Is this possible in just a query? Or should i do something programatically to apply the logic needed to whittle down the results of a query.
you can work with a temporary table using the myisam engine and a trick.
If you create the following temporary table:
create table tmp_company_sequence
( surname varchar(255)
,job_title varchar(255)
,company_name varchar(255)
,date_added date
,contact_code int
,counter int auto_increment
,primary key (contact_code,counter)
);
Now
insert into `tmp_company_sequence`( `surname`, `job_title`, `company_name`,`contact_code`,`date_added`)
SELECT DISTINCT `surname`, `job_title`, `company_name`,`contact_code`,`date_added`
FROM (`company_database`)
WHERE `employee_code` IN ('6', '7', '8', '9', '10', '11', '12', '13')
AND `turnover_code` IN ('5', '6', '7', '8')
AND `contact_code` IN ('16', '17', '26', '27', '9', '10', '30', '31', '23', '24', '12', '13') AND `industry_code` NOT IN ('22', '17', '35', '36')
order by contact_code, added_date desc;
Your temporary table will now hold all the contacts with a counter. The counter is increased for every contact of the same contact_code. SO the newest contact with a certain contact code will have counter = 1, the next recent will have counter = 2 and so on.
You can now do a
select *
from tmp_company_sequence
order by counter asc, date_added desc
limit 10;
This will give you a list of the latest contacts added over all contact_codes.
Edit:
I just realised this could be done with a single query, but it is even more ugly:
SELECT `surname`
, `job_title`
, `company_name`
, `contact_code`
FROM(
SELECT
`surname`
, `job_title`
, `company_name`
, `contact_code`
, `date_added`
, IF(contact_code = #prev_contact_code,#i:=#i+1,#i:=1) AS counter
, #prev_contact_code = contact_code
FROM
(`company_database`)
,(SELECT #i := 1)
WHERE `employee_code` IN ('6', '7', '8', '9', '10', '11', '12', '13')
AND `turnover_code` IN ('5', '6', '7', '8')
AND `contact_code` IN (
'16'
, '17'
, '26'
, '27'
, '9'
, '10'
, '30'
, '31'
, '23'
, '24'
, '12'
, '13'
)
AND `industry_code` NOT IN ('22', '17', '35', '36')
ORDER BY contact_code
, added_date DESC) sub
WHERE counter = 1
ORDER BY added_date DESC
LIMIT 10;
This does basically the same as the option with the temporary table, but it creates the counter in the fly by storing data from the previous column in global variables. It is messy but can be used within a single query.

Select with set order in mysql

I have a query like this:
SELECT title,id FROM table1 WHERE id IN ('2','7','4','10')
The result set is ordered by id by default, but I need it in the exact order of numbers in above set.
How can I achieve this?
The FIELD() function should be able to do this:
SELECT
title, id
FROM
table1
WHERE
id IN ('2', '7', '4', '10')
ORDER BY FIELD(id, '2', '7', '4', '10')
See also MySQL sort after argument in IN().