Ms Access SQL calculation from multiple rows - sql

I have the following query:
SELECT
InspectionID, Distance, Continuous, structural_grade
FROM
Conditions
WHERE
Continuous LIKE ("S%") OR Continuous LIKE ("F%")
ORDER BY
InspectionId ASC, Distance ASC
Which outputs:
262 60.80 S01 3
262 73.10 F01 3
262 82.60 S02 2
262 140.30 F02 2
263 30.80 S01 2
263 46.60 F01 2
380 4.60 S01 3
380 8.50 F01 3
380 9.80 S02 4
380 28.20 F02 4
380 77.70 S03 4
380 97.70 F03 4
The ordering is correct. However I'm stuck at what to do next.
Each "S" has a matching "F" with the same numbers Ex S01, F01. I need to access the Distance field of each "F" and minus "S" distance from it.
For examples F01 has a distance of 73.10 and S01 60.80 so the distance between is 12.3. I need to do this for each records and them numbers after the "S" and "F" can go really high yet will always match. ex. S999 - F999

Use the Mid() function to extract the digits from your Continuous field: Mid("S01", 2) yields "01". Then use those digits when you join the F and S rows.
With your sample data in Access 2010, the following query gave me this result set:
SELECT
f.InspectionID,
f.Continuous,
s.Continuous,
f.Distance AS F_distance,
s.Distance AS S_distance,
f.Distance - s.Distance AS F_minus_S
FROM
Conditions AS f
INNER JOIN
(
SELECT
InspectionID,
Continuous,
Distance,
Mid([Continuous],2) AS digits_only
FROM Conditions
WHERE Continuous ALike 'S%'
) AS s
ON
f.InspectionID = s.InspectionID
AND Mid(f.[Continuous],2) = s.digits_only
WHERE f.Continuous ALike 'F%'
ORDER BY f.InspectionId ASC, f.Distance ASC;
I included several columns which I doubt you want in your final query. But I think they can be useful during development and testing.
Beware the Access query designer will complain it can't represent that join condition in Design View. If you set up the join in SQL View, you can then run the query without Access complaining.

SELECT a.continuous AS 'S Continuous',
a.distance AS 'S Distance',
b.continuous AS 'F Continuous',
b.distance AS 'F Distance',
abs(a.distance - b.distance) AS 'Difference'
FROM Conditions a
INNER JOIN Conditions b
ON a.InspectionID = b.InspectionID
AND substring(a.continuous,2,len(a.continuous)-1) = substring(b.continuous,2,len(b.continuous)-1)
WHERE a.Continuous LIKE 'S%'
AND b.Continuous LIKE 'F%'
ORDER BY a.InspectionId ASC, a.Distance ASC

Related

Select from Multiple tables using Where, Max and SUM functions

I'm trying to get the following results,
based on my current WHERE statement I get several records which are from the same project_id, I'm interested in the latest based on id
from the second table I get multiple rows due to amount field, this could have several entries some additive or deductive. I would like to sum this amount and separate the deductive and additive
all of these resulst I want grouped by project_id so that I only have one row for each project_id
Table uco1
project_id
OrigProjName_TB
status
id
Table ucoline
record_id
amount
SELECT
a.project_id,
a.OrigProjName_TB,
a.CO_NewContract_CA,
a.con_amount_ca,
a.co_changeorderdate_do,
a.co_changeid_tb,
a.co_thiscoamount_ca,
a.OrigProjID_TB,
a.PIF_SpecNumber_TB,
a.CO_TITLE_TB,
a.status,
b.amount
FROM unifier_uco1 a
LEFT JOIN unifier_uco1_lineitem b
ON a.id = b.record_id
WHERE a.status = 'Authorized' OR a.status = 'Ratified'
What I have so far is this...
project_id
OrigProjName_tb
status
id
record_id
amount
2103
demo2
Authorized
786
786
142418
2103
demo2
Authorized
832
832
-523961
2103
demo2
Authorized
784
784
458228
2103
demo2
Authorized
784
784
67565
2100
demo3
Ratified
774
774
-852.85
2100
demo3
Ratified
774
774
4557
What I would like to see is the following;
project_id
OrigProjName_tb
status
id
record_id
additive
deductive
2103
demo2
Authorized
832
832
-523961
2100
demo3
Ratified
774
774
4557
-852.85
unfortunately for me I'm very new at this and just know a couple of basic functions. I even tried creating separate tables with basic functions to try and split up each function and later try to join all into one. This also resulted in a mess since I'm not familiar with all the different functions and statements.
I appreciate your help in advance and also, if you can provide best place to learn I would greatly appreciate that as well.
Thanks,

Join tables where no common field exists and based on ID columns

This question seems hard to phrase, but after explaining my situation it should be easy to understand. I have two tables: one called INSTRUCTORS that holds instructor data and another called LIST_OPTION_ITEM that holds the ID values of different ID columns stored in the INSTRUCTORS table. A third and possibly important table to include is LIST_OPTION_TYPE, which contains the IDs of whatever ID column there is in INSTRUCTORS. Perhaps it would be easier to explain by showing sample data and my desired output.
INSTRUCTORS
RANK_ID
SPECIALTY_ID
DUTY_TITLE_ID
SERVICE_BRANCH_ID
STATUS_ID
UNIT_ID
OFFICE_SYMBOL_ID
1354
319
931
2604
1378
1406
1429
LIST_OPTION_ITEM
OPTION_ITEM_ID
OPTION_TYPE_ID
ITEM_VALUE
1354
22
CAPT
319
20
CBRN TRAUMA NURSE
931
21
IDMT-Squadron Medical Element
2604
128
46N NURSE
1378
23
USA
1406
24
Guard
1429
126
CERFP
LIST_OPTION_TYPE
OPTION_TYPE_ID
OPTION_TYPE
20
Specialty
21
Duty_Title
22
Rank
23
Service_Branch
24
Status
126
Unit
128
Office_Symbol
It is important to note that I cannot join INSTRUCTORS and LIST_OPTION_ITEM, as there is no common column. However, LIST_OPTION_ITEM and LIST_OPTION_TYPE can join on OPTION_TYPE_ID. My desired output from a SELECT query:
Rank
Specialty
Duty Title
Service Branch
Status
Unit
Office Symbol
CAPT
CBRN TRAUMA NURSE
IDMT-Squadron Medical Element
46N NURSE
USA
Guard
CERFP
I've tried some solutions but can't come up with anything. Do I need a cross join or something? Help would be much appreciated.
I tried to do with Pivot and unpivot functions
below is sample sql:
with inst as (select inst_id, col, col_id
from (select rownum as inst_id, a.* from instructor a)
unpivot
(col_id for col in (status_id as 'STATUS',rank_id as 'RANK',specialty_id as 'SPECIALTY',duty_title_id as 'DUTY_TITLE')
))
select * from
(select inst_id,col,item_value from inst,
(select a.option_type,b.option_item_id,b.item_value from LIST_OPTION_TYPE a, list_option_id b
where a.option_type_id = b.option_type_id) opt
where inst.col = upper(option_type)
and option_item_id = col_id)
pivot
(max(item_value)
for col in ('STATUS','RANK','SPECIALTY','DUTY_TITLE')
) order by inst_id;
this will give desired output

How to fetch the summation of three columns from three tables in SQL?

whenever I am fetching the sum from one single table, the output is correct. But whenever I combine three/two separate table at that time the output becomes wrong.
my SQL for a single table is:
select users.name, SUM(BC.individual_cost) as breakfast_cost
from breakfast_orders BO, breakfast_costs BC,users
WHERE (BO.date=BC.date) and (BO.user_id=users.id)
GROUP BY(BO.user_id)
and here the output is:
name breakfast_cost
Munna Khandakar 300
Afifa Marowa Anha 180
Fouzia Kabir 50
Atiya Anam Afra Riya 50
in the same way, there are also 2 tables which gives a particular result which is correct. But when ever I join them, the overall result changes.
when I join them like this:
select users.name, SUM(BC.individual_cost) as breakfast_cost, SUM(LC.individual_cost) as lunch_cost, SUM(DC.individual_cost) as dinner_cost
from breakfast_orders BO, breakfast_costs BC,users, lunch_orders LO, lunch_costs LC, dinner_orders DOr, dinner_costs DC
WHERE (BO.date=BC.date) and (BO.user_id=users.id) AND (LO.date=LC.date) AND (LO.user_id=users.id) AND (DOr.date=DC.date) AND (DOr.user_id=users.id)
GROUP BY(users.id)
then the result becomes
name breakfast_cost lunch_cost dinner _cost
Munna Khandakar 2700 3222 4878
Afifa Marowa Anha 720 552 968
Fouzia Kabir 100 76 242
Atiya Anam Afra Riya 100 76 242
here, only by observing the breakfast_cost we can say that the query in not OK. SO if any one help me then I will be very grateful to him.
TIA
As #jarlh suggests better to use the explicit joins.
Try the Following
select u.name,
SUM(BC.individual_cost) as breakfast_cost,
SUM(LC.individual_cost) as lunch_cost,
SUM(DC.individual_cost) as dinner_cost
from users u
Left Join breakfast_orders BO on BO.user_id=u.id
Left Join breakfast_costs BC on BO.date=BC.date
Left Join lunch_orders LO on LO.user_id=u.id
Left Join lunch_costs LC on LO.date=LC.date
Left Join dinner_orders DO on DO.user_id=u.id
Left Join dinner_costs DC on DO.date=DC.date
Where not (BO.user_id is null and LO.user_id is null and DO.user_id is null)

Trouble pivoting data in DB2

Before this one is marked as duplicate please know I have done my research on Pivoting in DB2 (even though DB2 doesnt have PIVOT) from these links
Pivoting in DB2 on SO and IBM Developers, but I just cant make sense of how to do it with my Data and need some help. I tried to manipulate my string using examples from both of those links and could not get it to work. Im not asking for anyone to write the full code for me, but just give me a point in the right direction on how to change my string to retrieve the desired result. Thank you in advance.
Current String:
SELECT
cfna1 AS "Customer Name", cfrisk AS "Risk Rating", cfrirc AS "Rated By", date(digits(decimal(cfrid7 + 0.090000, 7, 0))) AS "Risk Rated Date",cfuc3n3 AS "Credit Score", date(digits(decimal(cf3ud7 + 0.090000, 7, 0))) AS "CR Date"
FROM cncttp08.jhadat842.cfmast cfmast
WHERE cfcif# IN ('T000714', 'T000713', 'T000716', 'T000715')
ORDER BY
CASE cfcif#
WHEN 'T000714' THEN 1
WHEN 'T000713' THEN 2
WHEN 'T000716' THEN 3
WHEN 'T000715' THEN 4
END
Result as expected from String:
Customer Name | Risk Rating | Rated By | Risk Rated Date | Credit Score | CR Date
Elmer Fudd 8 MLA 2018-02-08 777 2018-02-08
Result I would like to achieve:
Elmer Fudd
Risk Rating 8
Rated By MLA
Risk Rated Date 2018-02-08
Credit Score 777
CR Date 2018-02-08
Use unpivot method suggested in developers link and use cast to convert all columns to varchar.
Example:
select st1.id1, unpivot1.col1, unpivot1.val1
from (
select id1, char1 , date1, number1
from sometable
) st1,
lateral (values
('char col', cast(st1.char1 as varchar(100))),
('date col', cast(st1.date1 as varchar(100))),
('number col', cast(st1.number1 as varchar(100)))
) as unpivot1 (col1, val1)
order by st1.id1
I don't think that output is possible in sql -- do you mean something like this?
id_group Data_Type Value
1 Name Elmer Fudd
1 Risk Rating 8
1 Rated By MLA
1 Risk Rated Date 2018-02-08
1 Credit Score 777
1 CR Date 2018-02-08
To do this we need another column that brings all the elements together -- I called it "id_group" this is the column that identifys the group

Why does my SQL syntax show null?

I am little perplexed on why my result of this statement shows null in the Project_ID. I took a look at the below post and tried the inner join instead but the result was futile, the same as with the left join. I have only two distinct Project_ID. For some odd reason, the Name is being stated again with the Count added from the previous listings. Why is it doing this and how can I fix this? Please provide your advice.
Why does my SQL query return rows with NULL? It should never return rows with NULL
select dp."Name",count(dp."Name") Count,max(to_char(ft."Hours",'9,999')) "Maximum Hours Worked",
max(ft."Salary"::money) "Maximum Salary",
ft."Project_ID"
from facttable ft
left join alldatainput dp on dp."alldatainputpk" = ft."alldatainputfk"
group by rollup(dp."Name",ft."Project_ID")
Result:
Name Count Maximum Hours Worked Maximum Salary Project_ID
Hulk Hogan 157 3,500 $432,995.00 LFC
Hulk Hogan 43 3,499 $550,000.00 PCR
Hulk Hogan 200 3,500 $550,000.00 (null)
Andre the Giant 42 5,300 $870,000.00 PCR
Andre the Giant 42 5,300 $870,000.00 (null)
Bret Hart 5 3,675 $512,000.00 LFC
Bret Hart 10 4,193 $716,510.00 PCR
Bret Hart 15 4,193 $716,510.00 (null)
Winnie the Pooh 561 5,600 $929,654.00 PCR
Winnie the Pooh 561 5,600 $929,654.00 (null)
1000 5,600 $929,654.00 (null)
Grouping Sets
select
dp.Name,count(dp."Name") Count,
max(to_char(ft."Hours",'9,999')) "Maximum Hours Worked",
max(ft."Salary"::money) "Maximum Salary",
ft."Project_ID"
from
facttable ft
left join
alldatainput dp on dp."alldatainputpk" = ft."alldatainputfk"
group by grouping sets ((dp."Name",ft."Project_ID"), ())