SQL select command SUM across 3 related tables - sql

I've changed my DB structure to make it more future proof. Now I'm having trouble with the new select query.
I have table called activities that has a list of activities and how many steps per minute that activity was worth. The table was structred like this:
Activities
id act_name act_steps
12 Boxing 250
14 Karate 300
17 Yoga 89
I have another table called distance that is structed like this:
Distance
id dist_activity_id dist_activity_duration member_id
1 12 60 12
2 14 90 12
3 17 30 12
I have the query that would SUM and produce a total for all activities in the distance table
SELECT ROUND(SUM(act_steps * dist_activity_duration / 2000),2) AS total_miles
FROM distance,
activities
WHERE activities.id = distance.dist_activity_id
This worked fine.
To future proof it incase the number of steps for an activity changes I've setup a table called steps that is structured like this:
Steps
id activity_steps
1 6
2 250
3 300
4 89
I then updated the activities table, removing the act_steps column and replacing it with steps_id so it now looks like this:
Updated activities
id act_name steps_id
12 Boxing 2
14 Karate 3
17 Yoga 4
I'm not sure how to create the select command to get the SUM using the new structure.
Could someone please help me with this?
Thanks
Wayne

Learn to use proper JOIN syntax! Your query should look like:
SELECT ROUND(SUM(a.act_steps * d.dist_activity_duration / 2000), 2) AS total_miles
FROM distance d JOIN
activities a
ON a.id = d.dist_activity_id;
If you need to lookup the steps, then add another JOIN:
SELECT ROUND(SUM(s.activity_steps * d.dist_activity_duration / 2000), 2) AS total_miles
FROM distance d JOIN
activities a
ON a.id = d.dist_activity_id JOIN
steps s
ON s.id = a.steps_id;

Related

Grouping and Summing Totals in a Joined Table

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.

Create SQL query with dynamic WHERE statement

I'm using Postgresql as my database, in case that's helpful, although I'd like to find a pure SQL approach instead of a Postgresql specific implementation.
I have a large set of test data obtained from manufacturing a piece of electronics and I'd like to take that set of data and extract from it which units met certain criteria during test, ideally using a separate table that contains the test criteria from each step of manufacturing.
As a simple example, let's say I check the temperature readback from the unit in two different steps of the test. In step 1, the temperature should be in the range of 20C-30C while step 2 should be in the range of 50C-60C.
Let's assume the following table structure with a set of example data (table name 'test_data'):
temperature step serial_number
25 1 1
55 2 1
19 1 2
20 2 2
and let's assume the following table that contains the above mentioned pass criteria (table name 'criteria'):
temperature_upper temperature_lower step
20 30 1
50 60 2
At the moment, using a static approach, I can just use the following query:
SELECT * FROM test_data WHERE
( test_data.step = 1 AND test_data.temperature > 20 AND test_data.temperature < 30 ) OR
( test_data.step = 2 AND test_data.temperature > 50 AND test_data.temperature < 60 );
which would effectively yield the following table:
temperature step serial_number
25 1 1
55 2 1
I'd like to make my select query more dynamic and instead of begin statically defined, make it construct itself off of a list of results from the test_criteria table. The hope is to grow this into a complex query where temperature, voltage and current might be checked in step 1 but only current in step 2, for example.
Thanks for any insight!
You can solve using a join between the tables
SELECT t.*
FROM test_data t
INNER JOIN criteria c ON t.step = c.step
AND t.temperature > c.temperature_upper
AND t.temperature < c.temperature_lower
OR if you want >= and <=
SELECT t.*
FROM test_data t
INNER JOIN criteria c ON t.step = c.step
AND t.temperature netween c.temperature_upper AND c.temperature_lower

Extract only variables which is greater than other table in influxDB

I am using influxDB and I would like to extract some values which is greater than certain threshold in other table.
For example, I have two tables as shown in below.
Table A
Time value
1 15
2 25
3 9
4 22
Table B
Time threshold
1 16
2 12
3 13
4 15
Give above two tables, I would like to extract three values which is greater than first row in Table B. Therefore what I want to have is as below.
Time value
2 25
4 22
I tried it using below sql query, but it didn't give any correct result.
select * from data1 where value > (select spec from spec1 limit1);
Look forward to your feedback.
Thanks.
Integrate the condition in an inner join:
select * from tableA as a
inner join tableB as b on a.id=b.id and a.value > b.threshold
When your time column doesn't only include integer values, you have to format the time and join on a time range. Here is an example:
SQL join on time range

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.

SQL query, multyplying in select with Sum

I have 2 tables in SQL database.
Company_Shares
HolderOfShares NumberOfShares ShareOfComapy
A 100 Nova
A 30 Samsung
B 40 Nova
C 70 Hyper
A +20 Samsung
B +50 Nova
Price_of_single_Share
ShareOfComapny PricePerShare
Nova 10
Samsung 17
Hyper 13
Via this two tables I need to create a query which sums up the NumberOfShares for each HolderOfShares and multyply the number of shares with its price and order it by the totaly cost of shares. Final example should looks like that:
HolderOfShares TotalCostOfItsShares
A 1850
C 910
B 900
Could anybody help me with this query please.
If the question is going to be answered, the answer might as well be correct:
SELECT cs.HolderOfShares,
SUM(cs.NumberOfShares * poss.PricePerShare) as TotalCostOfItsShares
FROM Company_Shares cs JOIN
Price_of_single_Share poss
ON cs.ShareOfCompany = poss.ShareOfCompany
GROUP BY cs.HolderOfShares
ORDER BY TotalCostOfItsShares DESC;
Note: I assume that ShareOfComapy is a misspelling.
join those two tables
SELECT a.HolderOfShares, SUM(a.NumberOfShares) * b.PricePerShare as TotalCostOfItsShares FROM Company_Shares as a
JOIN Price_of_single_Share as b ON b.ShareOfComapy = a.ShareOfComapy
GROUP BY a.HolderOfShares