Grouping and Summing Totals in a Joined Table - sql

I have two tables Medication and Inventory. I'm trying to SELECT all the below details from both tables but there are multiple listings of medication ids with different BRANCH_NO also in the INVENTORY table (the primary key in INVENTORY is actually BRANCH_NO, MEDICATION_ID composite key)
I need to total up the various medication_IDs and also join the tables in one SELECT command and display all the infomation for each med (there are 5) with a total sum of each med at the end of each row. But im getting all muddled trying Group by and Sum and at one point partition. Help please I'm new to this.
Below is the latest non working version - but it doesn't display
Medication Name
Medication Desc
Manufacturer
Pack Size
like i chanced it might.
SELECT I.MEDICATION_ID,
SUM(I.STOCK_LEVEL)
FROM INVENTORY I
INNER JOIN (SELECT MEDICATION_NAME, SUBSTR(MEDICATION_DESC,1,20) "Medication Description",
MANUFACTURER, PACK_SIZE FROM MEDICATION) M ON MEDICATION_ID=I.MEDICATION_ID
GROUP BY I.MEDICATION_ID;
For the data imagine I want this sort of output:
MEDICATION_ID MEDICATION_NAME STOCK_LEVEL OtherColumns.....
1 Alpha 10
2 Bravo 20
3 Charlie 20
1 Alpha 30
4 Delta 10
5 Echo 20
5 Echo 40
2 Bravo 10
grouping and totalling into this:
MEDICATION_ID MEDICATION_NAME STOCK_LEVEL OtherColumns.....
1 Alpha 40
2 Bravo 30
3 Charlie 20
4 Delta 10
5 Echo 60
I can get this when its just one table but when Im trying to join tables and also SELECT things its just not working.
Thanks in advance guys. I appreciate it may be a simple solution, but it will be a big help.

You need to write explicitly all non-aggregated columns into both SELECT and GROUP BY lists ( Btw, no need to use a nested query, and if it's the case MEDICATION_ID column is missing in it ) :
SELECT I.MEDICATION_ID, M.MEDICATION_NAME, SUM(I.STOCK_LEVEL) AS STOCK_LEVEL,
SUBSTR(M.MEDICATION_DESC,1,20) "Medication Description", M.MANUFACTURER, M.PACK_SIZE
FROM INVENTORY I
JOIN MEDICATION M ON M.MEDICATION_ID = I.MEDICATION_ID
GROUP BY I.MEDICATION_ID, M.MEDICATION_NAME, SUBSTR(M.MEDICATION_DESC,1,20),
M.MANUFACTURER, M.PACK_SIZE;
This way, you'll be able to return all the listed columns.

Related

SQL query to order sum of a column

I have the following tables:
Drivers table, with a Driver_Code column
Route_files table, with a Driver_Code column and a Route_Code column
Routes table, with a Route_Code column and a Kilometers column
For every entry in the Drivers table there may be more than 1 entry in the Route_files table with the same Driver_Code. For every entry in the Route_files table, there is only one entry in the Routes table with the same Route_Code.
What I am trying to do is order the Drivers based on the total number of kilometers that they drove. So if I have the following data:
Drivers:
Driver_Code
2
3
4
Route_files:
Driver_Code Route_Code
2 20
2 50
2 30
3 30
4 40
Routes:
Route_Code Kilometers
20 1231
30 9
40 400000
50 24234
Then Driver 2 drove routes 20 30 and 50 so the total kilometers is 25474. Similarly driver 3 drove 9km and driver 4 drove 400000. The SQL query that I need should output:
Driver_Code Total_km
4 400000
2 25474
3 9
I tried to use an inner join on the Route_files and Routes tables to obtain a single "table" with all the necessary information, hoping that I could further use this obtained table, but couldn't figure out how to do that. I am working in dBase 2019(and can't change to something better, unfortunately). Any hints and ideas are appreciated!
I finally managed to do it. This is the working query:
select
Driver_Code,
SUM(km) as Total_km
from
Route_files
inner join Routes on Route_files.Route_Code = Routes.Route_Codes
GROUP BY
Route_files.Driver_Code
ORDER BY
Total_km Descending
Initially I was doing select Driver_Code, km, SUM(km) and when trying to do GROUP BY, dBase was forcing me to group by Driver_Code as well as km, which meant that the SUM function was being applied to every single entry instead of on all the entries of a single Driver_Code, which is what I needed. Now I finally understand what GROUP BY does!
Thanks everyone for your comments!

Total Sum SQL Server

I have a query that collects many different columns, and I want to include a column that sums the price of every component in an order. Right now, I already have a column that simply shows the price of every component of an order, but I am not sure how to create this new column.
I would think that the code would go something like this, but I am not really clear on what an aggregate function is or why I get an error regarding the aggregate function when I try to run this code.
SELECT ID, Location, Price, (SUM(PriceDescription) FROM table GROUP BY ID WHERE PriceDescription LIKE 'Cost.%' AS Summary)
FROM table
When I say each component, I mean that every ID I have has many different items that make up the general price. I only want to find out how much money I spend on my supplies that I need for my pressure washers which is why I said `Where PriceDescription LIKE 'Cost.%'
To further explain, I have receipts of every customer I've worked with and in these receipts I write down my cost for the soap that I use and the tools for the pressure washer that I rent. I label all of these with 'Cost.' so it looks like (Cost.Water), (Cost.Soap), (Cost.Gas), (Cost.Tools) and I would like it so for Order 1 it there's a column that sums all the Cost._ prices for the order and for Order 2 it sums all the Cost._ prices for that order. I should also mention that each Order does not have the same number of Costs (sometimes when I use my power washer I might not have to buy gas and occasionally soap).
I hope this makes sense, if not please let me know how I can explain further.
`ID Location Price PriceDescription
1 Park 10 Cost.Water
1 Park 8 Cost.Gas
1 Park 11 Cost.Soap
2 Tom 20 Cost.Water
2 Tom 6 Cost.Soap
3 Matt 15 Cost.Tools
3 Matt 15 Cost.Gas
3 Matt 21 Cost.Tools
4 College 32 Cost.Gas
4 College 22 Cost.Water
4 College 11 Cost.Tools`
I would like for my query to create a column like such
`ID Location Price Summary
1 Park 10 29
1 Park 8
1 Park 11
2 Tom 20 26
2 Tom 6
3 Matt 15 51
3 Matt 15
3 Matt 21
4 College 32 65
4 College 22
4 College 11 `
But if the 'Summary' was printed on every line instead of just at the top one, that would be okay too.
You just require sum(Price) over(Partition by Location) will give total sum as below:
SELECT ID, Location, Price, SUM(Price) over(Partition by Location) AS Summed_Price
FROM yourtable
WHERE PriceDescription LIKE 'Cost.%'
First, if your Price column really contains values that match 'Cost.%', then you can not apply SUM() over it. SUM() expects a number (e.g. INT, FLOAT, REAL or DECIMAL). If it is text then you need to explicitly convert it to a number by adding a CAST or CONVERT clause inside the SUM() call.
Second, your query syntax is wrong: you need GROUP BY, and the SELECT fields are not specified correctly. And you want to SUM() the Price field, not the PriceDescription field (which you can't even sum as I explained)
Assuming that Price is numeric (see my first remark), then this is how it can be done:
SELECT ID
, Location
, Price
, (SELECT SUM(Price)
FROM table
WHERE ID = T1.ID AND Location = T1.Location
) AS Summed_Price
FROM table AS T1
to get exact result like posted in question
Select
T.ID,
T.Location,
T.Price,
CASE WHEN (R) = 1 then RN ELSE NULL END Summary
from (
select
ID,
Location,
Price ,
SUM(Price)OVER(PARTITION BY Location)RN,
ROW_number()OVER(PARTITION BY Location ORDER BY ID )R
from Table
)T
order by T.ID

How calc Rank with this data in my database?

i have table that store questions each question have different answers and each answer have different weight and now i want to Calculation the rank but i don't now how do this.please help me
i use sql server
i have this table stored answers and weight of each answer
AdminQuesAns
=======================
Id QuesId Ans Value
10 1000 Yes 10
11 1000 somewhat 5
12 1000 No 0
10 1001 Yes 0
12 1001 No 10
and this table store Customer answers
AdminRank
==================================
Id SDId QuesId AnsValue
1 100 1000 10
2 100 1001 0
You can use the below query.
1.
Select SDId ,b.QuesId,
((sum(a.AnsValue) *100)/(Select sum(c.value)
from AdminQuesAns c where c.QuesId =b.QuesId))as'Rank'
from AdminRank a join AdminQuesAns b on a.QuesId=b.QuesId and value=AnsValue
group by SDId ,b.QuesId
This is how I'd go about it.
This has an inner query which gets the max value for each question, then the outer query pairs those with the values from the individual answers, sums across the questions and calculates one as a percentage of the other.
I'm also grouping by SDId, on the assumption that that is the ID of the person filling out the survey.
SELECT
ar.SDId,
100 * cast(sum(ar.AnsValue) as numeric(5,2)) / sum(mv.maxValue) as Rank
FROM
AdminRank ar
JOIN
(
SELECT
qa.QuesId,
max(qa.Value) as maxValue
FROM
AdminQuesAns qa
GROUP BY
qa.QuesId
) mv on ar.QuesId = mv.QuesId
GROUP BY
ar.SDId
Depending on your data types you may be able to remove the cast part.

Find 'Most Similar' Items in Table by Foreign Key

I have a child table with a number of charact/value pairs for a given 'material' (MaterialID). Any material can have a number of charact values and may have several of the same name (see id's 2,3).
The table has a large number of records (8+ million). What I'm trying to do is find the materials that are the most similar to a supplied material. That is, when I supply a MaterialID, I would like an ordered list of the most similar other materials (those with the most matching charact/value pairs).
I've done some research but, I may be missing some key terms or just not conceptualizing the problem correctly.
Any hints as to how to go about this would be very much appreciated.
ID MaterialID Charact Value
1 1 ROT_DIR CCW
2 1 SPECIAL_FEATURE CATALOG_CP
3 1 SPECIAL_FEATURE CHROME
4 1 SCHEDULE 80
5 2 BEARING_TYPE SB
6 2 SCHEDULE 80
7 3 ROT_DIR CCW
8 3 SPECIAL_FEATURE CATALOG_HSB
9 3 BEARING_TYPE SP
10 4 NDE_STYLE W_FAN
11 4 BEARING_TYPE SB
12 4 ROT_DIR CW*
You can do this with a self join:
select t.materialid, count(*) as nummatches
from t join
t tmat
on t.Charact = tmat.Charact and t.value = tmat.value
where tmat.materialid = #MaterialId
group by t.materialid
order by nummatches desc;
Notes:
You might want to remove the specified material, by adding where t.MaterialId <> tmat.MaterialId to the where clause.
If you want all materials, then make the join a left join and move the where condition to the on clause.
If you want only one material with the most matches, use select top 1.
If you want all materials with the most matches when there are ties, use `select top (1) with ties.

Sum nr of sales on a typical article number SQL

it's pretty simple i guess but i can't get it to work.
I have a Sales table with theese columns
Date,Artnr,Amount
For example
20150326, 19929, 2
20150326, 10231, 1
20150326, 10001, 3
20150325, 19929, 4
Now i want to make a SQL that gives me the Artnr and the sum Amount back.So in the example above i sold 6 artnr 19929 at two different times. Now i want to sum the amount on the rows with the same artnr and add them togheter. Like this.
10231, 1
10001, 3
19929, 6
The closest i get is with this SQL
SELECT a.artnr (SELECT SUM(b.amount) FROM SALES b WHERE b.artnr = a.artnr)
FROM SALES a
My Problem here is that i still get all rows back but at least it gives me the right sum amount.
19929, 6
10231, 1
10001, 3
19929, 6
Can someone help me with this please.
Just use group by:
SELECT artnr, SUM(amount)
FROM SALES s
GROUP BY artnr;