count similar attribute value - mysql

I am working (practice) on a Data Set with below table structure. I have developed different queries and have been successful so far. However, two queries are troubling me and was wondering if you guys could point what I am doing wrong.
1: Need to extract top 10 AuthorAccountId that created the highest number of changes on the project 'abc'.
e.g returns the top 10 AuthorAccountId that created the highest number of changes on the project 'abc'. The query must return two columns: the authorId and the number of changes made each author.
Following is the query that I have developed but does not give me the desired result.
SELECT ch_authoraccountid,count(ch_project)
FROM t_change
WHERE ch_project LIKE 'abc'
ORDER BY ch_authoraccountId DESC
LIMIT 10
2: Return the names of authors who did not submit any change during the year 2017, ( this one is going to be sub query on t_change).
e.g Expected result should return the name of authors who did not bring any changes in the year 2017.
Following is the query
SELECT p_name
FROM t_people
WHERE p_accountid IN (SELECT ch_createdTime
FROM t_change
WHERE ch_createdTime != '2016-01-01')")
Ref : Yang, R. G. Kula, N. Yoshida and H. Iida, "Mining the Modern Code Review Repositories: A Dataset of People, Process and Product," 2016 IEEE/ACM 13th Working Conference on Mining SoftwareRepositories (MSR), Austin, TX, 2016, pp.
460-463.
https://github.com/kin-y/miningReviewRepo/wiki/Database-Schema

For the first query, try this :
SELECT ch_authoraccountid, COUNT(ch_project)
FROM t_change
WHERE ch_project = 'abc'
GROUP BY ch_authoraccountid
ORDER BY COUNT(ch_project) DESC
LIMIT 10
It will count the number of change in 'abc' project per authoraccountid.
For the second :
SELECT p_name
FROM t_people
WHERE p_accountid NOT IN (SELECT ch_authorAccountId
FROM t_change
WHERE ch_createdTime BETWEEN '20170101' AND '20171231')")

Related

Need to retrieve the most recent room type/Rateplan combination (mysql)

I will explain the logic:
I need to retrieve only the most recent room type/rate plan combinations from the rateplan_roomtypeTable.
room type ID and rate plan id are located in separate columns
there are 2 conditions that need to be met: all active room type/rate plan combinations need to be retrieved along with all room type/rate plan combinations that have produced even if they are not active. All these combinations need to be the most recent ones.
The desired results would be like the table I ll share with you:
Your help with the below query will be much appreciated:
select
Id
, RoomTypeId
, RateTypeId
,isactiveRateType
,isactiveRoomType
, RatePlanName
, RoomTypeName
FROM
rateplan_roomtypeTable
where
RateTypeId IN (select RateTypeId from ProductionTable where (cast(bookingdate as date) between date_add('day',-92, current_date) and date_add('day', -2, current_date)))
OR (isactiveRateType = 1 and isactiveRoomType = 1)
GROUP BY
1,2,3,4,5
Thank you

Extract the number of invoices of the current year in mysql

Goodmorning everyone.
I'm going crazy
I need to extract the number of invoices from the current year per customer.
in my table tbl_preventivi I have the field anagrafica_id for the customer and date_prev for the date of the invoice.
this is my code.
$anno = date('Y');
SELECT tbl_preventivi.anagrafica_id, Count(tbl_preventivi.preventivo_id) AS totale
FROM tbl_preventivi
GROUP BY tbl_preventivi.anagrafica_id, Year(tbl_preventivi.data_prev)
HAVING ((Year(tbl_preventivi.data_prev) = ".$anno.") AND (tbl_preventivi.anagrafica_id=".$_GET['anagrafica_id']."))
i am sure that in the test i am doing the result must be 1, instead the query is null.
if I remove
(Year(tbl_preventivi.data_prev) = ".$anno.") AND the query works and returns 6 (which is the number of invoices made even in previous years).
where am i wrong?
The simplest solution would be something like:
SELECT p.`anagrafica_id`,
COUNT(p.`preventivo_id`) as `totale`
FROM `tbl_preventivi` p
WHERE p.`anagrafica_id` = 12345 and YEAR(p.`data_prev`) = 9999
GROUP BY p.`anagrafica_id`;
Note: 12345 should be replaced with a sanitized customer number, and 9999 should be replaced with a sanitized and logical year. Prepared statements are your friend here.
If you wish to see all invoices for a customer across all years, you can do this:
SELECT p.`anagrafica_id`,
YEAR(p.`data_prev`) as `year`,
COUNT(p.`preventivo_id`) as `totale`
FROM `tbl_preventivi` p
WHERE p.`anagrafica_id` = 12345
GROUP BY p.`anagrafica_id`, `year`
ORDER BY `year` DESC;
Again, be sure to sanitize your inputs. In the famous words of Fox Mulder: Trust no one.

Find lowest value and coresponding code on asingle query mysql

I have a user table as follows
id name age
1 John 21
2. Mathan 23
3. Raj 21
4. Manoj 50
5 Krishnan 91
I want to find minimum age and its corresponding name. How can I do it with rails?
Can I do it in a single query?
Note: More than one names can have single age.
Is there a specific reason why you want to do it in a single query ?
If you can write 2 queries, I think you can just write :
User.where age: User.minimum(:age)
select age, group_concat(name) from table group by age order by age asc limit 1
You will need to process the results later on in ruby, but this gives all you need in one single query. Also i am assuming mysql, so might differ on other rdbms.
It gives exact output in mysql that you want try this
SELECT concat("[",name," ",age,"]") AS name
FROM TABLE
WHERE age =
(SELECT min(age)
FROM TABLE);

Selecting most recent as part of group by (or other solution ...)

I've got a table where the columns that matter look like this:
username
source
description
My goal is to get the 10 most recent records where a user/source combination is unique. From the following data:
1 katie facebook loved it!
2 katie facebook it could have been better.
3 tom twitter less then 140
4 katie twitter Wowzers!
The query should return records 2,3 and 4 (assume higher IDs are more recent - the actual table uses a timestamp column).
My current solution 'works' but requires 1 select to generate the 10 records, then 1 select to get the proper description per row (so 11 selects to generate 10 records) ... I have to imagine there's a better way to go. That solution is:
SELECT max(id) as MAX_ID, username, source, topic
FROM events
GROUP BY source, username
ORDER BY MAX_ID desc;
It returns the proper ids, but the wrong descriptions so I can then select the proper descriptions by the record ID.
Untested, but you should be able to handle this with a join:
SELECT
fullEvent.id,
fullEvent.username,
fullEvent.source,
fullEvent.topic
FROM
events fullEvent JOIN
(
SELECT max(id) as MAX_ID, username, source
FROM events
GROUP BY source, username
) maxEvent ON maxEvent.MAX_ID = fullEvent.id
ORDER BY fullEvent.id desc;

Complex MySQL COUNT query

Evening folks,
I have a complex MySQL COUNT query I am trying to perform and am looking for the best way to do it.
In our system, we have References. Each Reference can have many (or no) Income Sources, each of which can be validated or not (status). We have a Reference table and an Income table - each row in the Income table points back to Reference with reference_id
On our 'Awaiting' page (the screen that shows each Income that is yet to be validated), we show it grouped by Reference. So you may, for example, see Mr John Smith has 3 Income Sources.
We want it to show something like "2 of 3 Validated" beside each row
My problem is writing the query that figures this out!
What I have been trying to do is this, using a combination of PHP and MySQL to bridge the gap where SQL (or my knowledge) falls short:
First, select a COUNT of the number of incomes associated with each reference:
SELECT `reference_id`, COUNT(status) AS status_count
FROM (`income`)
WHERE `income`.`status` = 0
GROUP BY `reference_id`
Next, having used PHP to generate a WHERE IN clause, proceed to COUNT the number of confirmed references from these:
SELECT `reference_id`, COUNT(status) AS status_count
FROM (`income`)
WHERE `reference_id` IN ('8469', '78969', '126613', ..... etc
AND status = 1
GROUP BY `reference_id`
However this doesn't work. It returns 0 rows.
Any way to achieve what I'm after?
Thanks!
In MySQL, you can SUM() on a boolean expression to get a count of the rows where that expression is true. You can do this because MySQL treats true as the integer 1 and false as the integer 0.
SELECT `reference_id`,
SUM(`status` = 1) AS `validated_count`,
COUNT(*) AS `total_count`
FROM `income`
GROUP BY `reference_id`