I have two tables, Countries and Sums:
+------+---------+
| code | country |
+------+---------+
| 01 | France |
| 02 | Germany |
| 02 | Austria |
| 03 | Belgium |
| 04 | Belgium |
| 04 | Spain |
| 05 | Italy |
+------+---------+
+------+-----+
| code | sum |
+------+-----+
| 01 | 500 |
| 02 | 400 |
| 03 | 300 |
| 04 | 200 |
+------+-----+
I want to create a table code-sum-country. It's very easy of course, but I need to have exactly the same number of rows as in the table Sums.
+------+-----+---------+
| code | sum | country |
+------+-----+---------+
| 01 | 500 | France |
| 02 | 400 | Austria |
| 02 | 400 | Germany |
| 03 | 300 | Belgium |
| 04 | 200 | Spain |
| 04 | 200 | Belgium |
+------+-----+---------+
I want to have in the above table unique code values. So I need to remove some of them, it doesn't matter which one. My goal is to have only one row with the same code. For example the row
| 04 | 200 | Spain |
can remain or be deleted.
How can I do that?
Try this:
DELETE
FROM code_sum_country
WHERE code in
(SELECT code
FROM code_sum_country
GROUP BY code
HAVING COUNT (code) > 1)
AND country NOT IN
(SELECT MIN(country)
FROM code_sum_country
GROUP BY code
HAVING COUNT (code) > 1)
This will retain the country whose name is minimum in alphabetical order.
Change MIN(country) to MAX(country) if you want to retain the maximal ones.
Hope it helps :)
If you want to query sums and get one arbitrary country, you can use a correlated subquery:
select s.*,
(select top 1 c.country
from countries as c
where s.code = c.code
) as country
from sums as s;
I understand your question in such a way that the result is actually about code and sum, and an example of country is desired. Probably to give more meaning to your results and which country is actually returned is irrelevant... I therefore suggest a group by and a max or min on code, and max or min on country. See beneath.
PS: possibly it could be more usefull to define a different kind of name that is more meaningfull than country. But that is kind of bluntly to say without more info :).
select
min(code) as code
,[sum]
,min(country) as country
from TableAA
group by sum
Related
Say you're given the following table called Customers:
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | Hardik | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Ramesh | 25 | Ahmedabad | 6500.00 |
| 5 | Hardik | 27 | Delhi | 8500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
| 7 | Ramesh | 24 | Ahmedabad | 10000.00 |
+----+----------+-----+-----------+----------+
A lot of resources explaining group by statements would use an example like:
SELECT NAME, SUM(SALARY) FROM CUSTOMERS GROUP BY NAME; where the thing being 'selected' other than the field being 'grouped by' is a function like count or sum. But what happens if you did something like SELECT NAME, ADDRESS FROM CUSTOMERS GROUP BY NAME; - how exactly would the addresses be grouped together in a single record with the name. I know I can run this and find out the answer, but I want to understand the general logic - if anyone could assist that would be very much appreciated.
EDIT ANOTHER QUESTION:
In the new table above, if I did SELECT NAME, ADDRESS, group_concat(salary) FROM CUSTOMERS GROUP BY NAME; would this be ok, seeing as how the addresses are the same for each name?
If you say SELECT NAME, ADDRESS FROM CUSTOMERS GROUP BY NAME, you will get an error asking you to put an aggregation function around the ADDRESS column. For instance, you could write
SELECT NAME, MAX(ADDRESS) FROM CUSTOMERS GROUP BY NAME
I've got a table in SQL Server 2016 (I believe it was originally from 2008 or 2012 and it's just moved to the 2016 cluster) with patient events, the type of event, and the severity of the event (called a grade). There are several instances where the same patient will have multiple events occur but with varying grades. So, a sample of data will look something like this:
| Pt_id | Event | Grade |
+-------+----------------+-------+
| 01 | Pain | 2 |
| 01 | Pain | 4 |
| 01 | Nausea | 2 |
| 02 | Headache | 2 |
| 02 | Headache | 3 |
| 03 | Blurred Vision | 3 |
| 03 | Blurred Vision | 4 |
| 03 | Bluured Vision | 3 |
| 03 | Nausea | 4 |
| 03 | Nausea | 2 |
I'm trying to get the highest grade for each of the different events per patient. My desired output for that data would be as follows:
| Pt_id | Event | Grade |
+-------+----------------+-------+
| 01 | Pain | 4 |
| 01 | Nausea | 2 |
| 02 | Headache | 3 |
| 03 | Blurred Vision | 4 |
| 03 | Nausea | 4 |
I've tried using the the Top 1 incorporated into the query, the ROW_Number, Partition, and everything else Google has thrown at me but I get either too restricted of results (I'm getting around 30 rows but I actually went through the excel (I'm trying to do some QA here) and I should have just under 400 rows. I think that when I do these functions I'm missing something and it's grouping either all Pt_ids and just picking 1 row for all the Events for that Pt_id or it's doing that with the Event - and no matter what I try it won't give me one row per patient, per event, with the highest grade for that event and patient.
Although I've used SQL throughout the years, it's never been my primary function so your assistance is greatly appreciated!
Isn't this enough with use of GROUP BY with MAX() ?
SELECT Pt_id, Event, MAX(Grade)
FROM table t
GROUP BY Pt_id, Event;
If the table has more column other than only 3 columns, then use ROW_NUMBER() with TIES clause :
SELECT TOP (1) WITH TIES t.*
FROM table t
ORDER BY ROW_NUMBER() OVER (PARTITION BY Pt_id, Event ORDER BY Grade DESC);
use row_number window function
with cte as
(
select *,
row_number() over(partition by Pt_id ,Event by order by Grade desc) rn
from your_table
)select * from cte where rn=1
You have to use order by Grade descfor getting max value
I have a database table transaction with the following columns:
date | mccg | us_amount | country |
Sample contents are:
08/10/2016 22:00:56 | 003 | 10 | UK
14/12/2016 19:26:34 | 004 | 30 | GER
18/02/2017 05:06:22 | 018 | 100 | UK
10/03/2016 14:52:45 | 018 | 25 | UK
12/03/2016 18:02:22 | 018 | 02 | UK
I want to get a result as follows:
year_month_week | us_amount| country | mccg
2016-03-2 | 27 | UK | 018
2017-02-2 | 100 | UK | 01
I searched online for similar solutions but couldnt get any helpful ones.
I tried this query:
SELECT year_month_week as (?),us_amount,country,mccg
FROM transaction
WHERE country like 'UK' and mccg like '018'
GROUP BY year_month_week
ORDER BY year_month_week
But my problem is how to set year_month_week working, or whatever weekly format.
You can use to_char():
SELECT to_char(date, 'YYYY-MM-WW') as year_month_week,
SUM(us_amount) as us_amount, country, mccg
FROM transaction
WHERE country like 'UK' and mccg like '018'
GROUP BY year_month_week, country, mccg
ORDER BY year_month_week;
If you want other countries or mccgs, then remove the WHERE filtering.
I have been battling through this query/query design for sometime now and I thought it's time to ask the experts! Here's my table results:
ID | Status | date |
---------------------------------
05 | Returned | 20/6/2018 |
03 | Sent | 12/5/2018 |
01 | Pending | 07/6/2018 |
01 | Engaged | 11/4/2018 |
03 | Contacted | 16/4/2018 |
05 | Surveyed | 04/3/2017 |
05 | No Contact | 05/3/2017 |
How do I get it to return top/newest value for each ID:
ID | Status | date |
---------------------------------
05 | Returned | 20/6/2018 |
03 | Sent | 12/5/2018 |
01 | Pending | 07/6/2018 |
I've tried group by, TOP 1, Distinct and results still not what I wanted. Also, displaying the results by top 5% is won't do either as the ID can be more than just 3 types.
My QUERY below:
INSERT INTO TmpAllcomsEmployee ( StatusID, EmployeeID, CommunicationDate )
SELECT DISTINCT CommunicationLog.StatusID, TmpAllcomsEmployee.EmployeeID,
Max(CommunicationLog.CommunicationDate) AS MaxOfCommunicationDate
FROM CommunicationLog RIGHT JOIN TmpAllcomsEmployee ON
CommunicationLog.EmployeeID = TmpAllcomsEmployee.EmployeeID
GROUP BY CommunicationLog.StatusID, TmpAllcomsEmployee.EmployeeID
ORDER BY Max(CommunicationLog.CommunicationDate) DESC;
One method is a correlated subquery:
select cl.*
from CommunicationLog as cl
where cl.date = (select max(cl2.date)
from CommunicationLog as cl2
where cl2.EmployeeID = cl.EmployeeID
);
This gets the most recent record for each employee in CommunicationLog. You can join in the other table if you really need it. It does not seem unnecessary unless you are using it for filtering.
I need to search for the sum of the games made by specific developers. I have two tables:
_____________________________
|____________GAMES____________|
| Id | Title | id_dev | hits |
| 01 | abc | 1 | 20 |
| 02 | xyz | 2 | 15 |
| 03 | cde | 1 | 9 |
_______________
|__DEVELOPERS___|
| Id | Title |
| 01 | poi |
| 02 | asd |
| 03 | qwe |
I want result formatted like Developers title 40, where 40 is the sum of all hits of the games with the ID of this developer. How can I go about this?
SELECT developers.title, COUNT(count) AS total FROM (SELECT COUNT(games.hits) AS count
FROM games
GROUP BY id_dev
HAVING count > 1) as A
FROM developers
JOIN games
WHERE developers.id = games.id_dev
This is a simple join and aggregate, so you are overcomplicating things:
select d.id, d.title, sum(g.hits)
from games g join
developers d
on g.id_dev = d.id
group by d.id, d.title;