Issue with Union Sub-query - mysql

I'm attempting to use a union sub query to get the results for a couple different queries. What I'm looking to do is select all the players who hit a home run in the 2014 season, create a home run count for each player and find the average pitch speed of each home run. I'm also attempting to break things down by pitch type, my current code and result are as follows:
Select output.Batter_Name,
output.Qty,
output.speed,
output.avg_Speed,
output.break,
output.Type_Pitch,
Output.CH_Qty,
Output.CH_Pitch,
Output.Ch_Speed,
Output.CH_Avg_speed,
Output.CH_Break,
Output.CH_Type_Pitch
From(
SELECT
count(gameday.atbats.event) as Qty,
gameday.batters.name_display_first_last as Batter_Name,
gameday.pitches.type as Pitch,
gameday.pitches.start_speed as speed,
avg(gameday.pitches.start_speed) as avg_speed,
avg(gameday.pitches.break_length) as Break,
gameday.pitches.Pitch_type as Type_Pitch,
"0" as CH_Qty,
"0" as CH_Pitch,
"0" as Ch_Speed,
"0" as CH_Avg_speed,
"0" as CH_Break,
"0" as CH_Type_Pitch
FROM
gameday.atbats
JOIN
gameday.pitches ON gameday.atbats.num = gameday.pitches.gameAtBatID
AND gameday.pitches.gamename = gameday.atbats.gamename
INNER JOIN
gameday.batters ON gameday.atbats.batter = gameday.batters.ID
AND gameday.atbats.gamename = gameday.batters.gameName
INNER JOIN
gameday.pitchers ON gameday.atbats.pitcher = gameday.pitchers.ID
AND gameday.atbats.gamename = gameday.pitchers.gamename
WHERE
(gameday.atbats.event = 'Home Run')
AND gameday.pitches.type = 'x'
and gameday.pitches.Pitch_type = 'FF'
group by gameday.batters.name_display_first_last
UNION ALL
SELECT
"0" as Qty,
gameday.batters.name_display_first_last as Batter_Name,
"0" as Pitch,
"0" as Speed,
"0" as Avg_speed,
"0" as Break,
"0" as Type_Pitch,
count(gameday.atbats.event) as CH_Qty,
gameday.pitches.type as CH_Pitch,
gameday.pitches.start_speed as CH_speed,
avg(gameday.pitches.start_speed) as CH_avg_speed,
avg(gameday.pitches.break_length) as CH_Break,
gameday.pitches.Pitch_type as CH_Type_Pitch
FROM
gameday.atbats
JOIN
gameday.pitches ON gameday.atbats.num = gameday.pitches.gameAtBatID
AND gameday.pitches.gamename = gameday.atbats.gamename
INNER JOIN
gameday.batters ON gameday.atbats.batter = gameday.batters.ID
AND gameday.atbats.gamename = gameday.batters.gameName
INNER JOIN
gameday.pitchers ON gameday.atbats.pitcher = gameday.pitchers.ID
AND gameday.atbats.gamename = gameday.pitchers.gamename
WHERE
(gameday.atbats.event = 'Home Run')
AND gameday.pitches.type = 'x'
and gameday.pitches.Pitch_type = 'CH'
group by gameday.batters.name_display_first_last
) as Output
group by Output.Batter_name
A Sample of my results are below:
Batter_Name, Qty, speed, avg_Speed, break, Type_Pitch, CH_Qty, CH_Pitch, Ch_Speed, CH_Avg_speed, CH_Break, CH_Type_Pitch
A.J. Pollock 1 89 90 4.3 FF 0 0 0 0 0 0
Aaron Hicks 0 0 0 0 0 1 X 83 83 6 CH
The first player, Ellis shows that he had one home run on a FF, and zero on a CH. The 2nd player,Peirzynski, had 0 home runs on a FF, but 1 on a CH. The issue is that I know these players had home runs on both types of pitches, but the query is only one or the other, not both. My intended results are something like this:
Batter_Name, Qty, speed, avg_Speed, break, Type_Pitch, CH_Qty, CH_Pitch, Ch_Speed, CH_Avg_speed, CH_Break, CH_Type_Pitch
A.J. Pollock 1 89 90 4.3 FF 2 X 84 82 3.2 CH
Aaron Hicks 4 90 91 2.5 FF 1 X 83 83 6 CH
I'm thinking the issue has to be my setting some fields to 0, kind of like a place holder, but i cant seem to find a workable solution that gets me the results I want.

Related

Calculate sum when value changes

I am trying to build a system that will track vehicle fuelings, and have run into a problem with one report; determining fuel efficiency in distance/fuel. Sample data is:
odometer
fuel
partial_fillup
61290
10.3370
0
61542
6.4300
0
61735
4.3600
0
61994
7.5000
0
62242
5.4070
0
62452
8.1100
0
62713
5.7410
1
62876
9.4850
0
63243
6.1370
1
63499
10.7660
0
Where odometer is the total distance the vehicle has traveled, fuel is the number of gallons or liters put in, and partial_fillup is a boolean meaning the fuel tank was not completely filled if non-zero.
If the user fills the tank each time the query I can use is:
set #a = null;
select
odometer,
odometer-previousOdometer distance,
fuel,
(odometer-previousOdometer)/fuel mpg,
partial_fillup
from
(
select
#a as previousOdometer,
#a:=odometer,
odometer,
fuel/1000 fuel,
partial_fillup
from fuel
where
vehicle_id =1
and odometer >= 61290
order by odometer
) as readings
where readings.previousOdometer is not null;
However, when the user only partially fills the tank, the correct procedure would be to subtract the last full fueling from current odometer reading, then divide by the sum of all fuel since the previous odometer reading, so at odometer 63499, the calculate would be (63499-62876)/(10.7660+6.1370)
This will get the average used on the last ride:
select
odometer,
odometer-lag(odometer) over (order by odometer) as distance,
fuel,
(odometer-lag(odometer) over (order by odometer))/fuel as mpg
from fuel
output:
odometer
distance
fuel
mpg
61290
10.3370
61542
252
6.4300
39.1913
61735
193
4.3600
44.2661
61994
259
7.5000
34.5333
62242
248
5.4070
45.8665
62452
210
8.1100
25.8940
62713
261
5.7410
45.4625
62876
163
9.4850
17.1850
63243
367
6.1370
59.8012
63499
256
10.7660
23.7786
Or you can calculate the total drive distance, and the total amount of fuel used:
select
distance,
sum_fuel,
distance/sum_fuel as mpg
from (
select
f.odometer,
f.odometer-(select min(odometer) from fuel) as distance,
fuel,
sum_fuel
from fuel f
inner join (
select
odometer,
sum(fuel) over (order by R) as sum_fuel
from (
select
odometer,
fuel,
row_number() over (order by odometer) R
from fuel) x
) x on x.odometer = f.odometer
) x2
which will get next output, which will get closer to an average after a longer time of measurement:
distance
sum_fuel
mpg
0
10.3370
0.0000
252
16.7670
15.0295
445
21.1270
21.0631
704
28.6270
24.5922
952
34.0340
27.9720
1162
42.1440
27.5721
1423
47.8850
29.7170
1586
57.3700
27.6451
1953
63.5070
30.7525
2209
74.2730
29.7416
DBFIDDLE
I was able to figure it out after studying Luuk's answer. I'm sure there is a more efficient way to do this; I am not used to using variables in SQL. But, the answers are correct in the test data.
set #oldOdometer = null;
set #totalFuel = 0;
select
s.odometer,
format(fuel, 3) fuel,
s.distance,
format( distance / fuel, 2) as mpg
from (
select
partial_fillup as partial,
odometer,
(fuel+#totalFuel) as fuel,
#totalFuel as totalFuel,
#oldOdometer oldOdometer,
if ( partial_fillup, null,odometer - #oldOdometer ) as distance,
#totalFuel := if ( partial_fillup, #totalFuel + fuel, 0) as pastFuel,
#oldOdometer := if (partial_fillup,#oldOdometer,odometer ) as runningOdometer
from
fuel
order by
odometer ) s
where s.distance is not null
order by s.odometer
limit 1,999;
limit 1,999 simply there to skip the first row returned, since there is not enough data to calculate distance or mpg. On my copy of MySQL, doing this means you do not need to initialize the two variables (you don't have to include the set commands at the beginning), so it works with my reporting tool very well. If you do initialize them, you do not need the limit statement. Works assuming you don't have more than 999 rows returned.

Wrong data due to Joins

How can I remove unreal data that I'm getting after several joins that I ran.
my entire Query is:
SELECT
distinct vortex_dbo.vw_public_material_location.material_name
,vw_public_request_material_location_mir.material_request_id
,vw_public_request_material_location_mir.parttype_name
,operation_code
,vw_public_request_material_location_mir.result_name
,vw_public_request_material_location_mir.qdf_number
, requestor
,[vortex_hvc].[vortex_dbo].[material_request].created_by
,[vortex_hvc].[vortex_dbo].[material_request].created_datetime as time1
,[vortex_hvc].[vortex_dbo].[material_request].distribution_list
,[vortex_hvc].[vortex_dbo].[material_request].recipient_name
, DATEPART(WW,[vortex_hvc].[vortex_dbo].[material_request].created_datetime) as WW
,vw_public_request_material_location_mir.product_code_name
,task_name
,vw_public_request_material_location_mir.full_location_name
FROM [vortex_hvc].[vortex_dbo].[vw_public_request_material_location_mir]
left join request on vw_public_request_material_location_mir.material_request_id = request.request_key
left join vortex_dbo.material_request on vw_public_request_material_location_mir.material_request_id = vortex_dbo.material_request.material_request_id
left join vortex_dbo.vw_public_material_location on vw_public_request_material_location_mir.last_result_id = vortex_dbo.vw_public_material_location.last_result_id
left join vortex_dbo.vw_public_material_history on vw_public_request_material_location_mir.material_request_id like (substring(vw_public_material_history.comments,12,6))
where (vw_public_request_material_location_mir.qdf_number not like 'null' and vw_public_request_material_location_mir.qdf_number not like '')
and vw_public_request_material_location_mir.product_code_name like 'LAKE%'
and vw_public_request_material_location_mir.task_id not like 'null'
and (vw_public_request_material_location_mir.result_name like 'bin 100' or vw_public_request_material_location_mir.result_name like 'bin 01'
or vw_public_request_material_location_mir.result_name like 'bin 02' or vw_public_request_material_location_mir.result_name like 'pass')
and (requestor like 'BUGANIM, RINAT' and employee_name like 'BUGANIM, RINAT')
and ( DateDiff(DD,[vortex_hvc].[vortex_dbo].[material_request].created_datetime, getdate()) < 180)
and (concat('',substring(vortex_dbo.vw_public_material_location.comments,12,6)) like vw_public_request_material_location_mir.material_request_id
or vortex_dbo.vw_public_material_location.comments like 'Changed by Matrix Transaction Handler' or vortex_dbo.vw_public_material_location.comments like 'Unit Ownership:%')
and (unit_number = vortex_dbo.vw_public_material_location.material_name or unit_number is null)
and vortex_dbo.vw_public_material_location.material_name like 'D7QM748200403'
order by vortex_dbo.vw_public_material_location.material_name desc
The results I'm getting are:
two rows that only the 2nd one contains true data.
material_name material_request_id parttype_name operation_code result_name qdf_number requestor created_by time1 WW product_code_name task_name full_location_name
D7QM748200403 332160 H6 4GXDCV K Y 7295 BIN 01 Q1T5 BUGANIM, RINAT SMS_Interface 2017-12-03 20:27:30.327 49 CANNON LAKE Y 2+2 PPV-M SAMPLE: QDF INVENTORY
D7QM748200403 332176 H6 4GXDCV K Y 7295 BIN 01 Q1T5 BUGANIM, RINAT SMS_Interface 2017-12-03 21:02:33.247 49 CANNON LAKE Y 2+2 PPV-M SAMPLE: QDF INVENTORY
What can I do in order to retrieve true data only?, I have more cases like this.
Thanks!!

sql/mysql Multiple results from one value

I am working on an integration output report to feed into a purchase order system.
All of the possible items are straightforward except for one particular item, which has to be broke out into multiple components.
The current code:
select concat("M", id) as ID, MaterialId, quantity, uom,
crew_job.JobSubNbr, crew_job.EmployeeId, crewjob_schedule_actual.startTime
from crewjob_material_actual
inner join crew_job on crewjob_material_actual.crew_job_id = crew_job.crew_job_id
inner join crewjob_schedule_actual on
crewjob_material_actual.crew_job_id = crewjob_schedule_actual.crew_job_id
And the current results output:
What I need to do is something of the effect of (and this is in plain English)
IF "MaterialID" = '3'
THEN [the results should be] show me 3 rows of data such as:
ID = MZ4931, MaterialID = 100, Qty = 0.25, UOM = 1 .... (all else the
same) ID = MZ4932, MaterialID = 101, Qty = 0.50, UOM = 1 .... (all
else the same) ID = MZ4933, MaterialID = 102, Qty = 0.33, UOM = 2
.... (all else the same)
Essential, item #3 is a "combined item" that I need to apply based on a standard ratio, where 1 unit of Item 3 is equal to .25 of item 100, .50 of item 101, and 0.33 of item 102. I'm sure this isn't too difficult but I was having a hard time searching.

how to create an sql view based on calculated vales?

Hie lets assume we have the following table
TABLE NAME : DRINGE
__________________________________________________
ID PRODUCT MACHINE MASS STATE
01 1.76ann HRB 50 inlet
02 1.76ann HRB 38 inlet
03 2.55ann GUDO 45 outlet
04 95mm x 4 GUDO 36 dispatched
___________________________________________________
And the following formula:
(inlet –outlet ) +outlet – dispatched = [resulted displayed to new view]
And the values to be substituted are:
INLET = 50 , 38
OUTLET=45
DISPATCHED = 36
So substituting in the above formula
[(inlet –outlet ) +outlet – dispatched = [resulted displayed to new view]
We get this
(50+38 – 45 ) + 45 – 36 = 52
What I want is for the result ie 52 to be displayed in an sql view like the following view
Dringe VIEW
_____________
Total_summary|
_____________|
52 |
_____________|
.
Does anyone have any idea of an sql query I can use to do this ?
I rily need your help am stuck again, thanx in advance.
The below will follow your formula
CREATE VIEW DRINGEView AS
SELECT sum(case when state = 'inlet' then mass else 0 end) -
sum(case when state = 'outlet' then mass else 0 end)+
sum(case when state = 'outlet' then mass else 0 end) -
sum(case when state = 'dispatched' then mass else 0 end) AS Total_summary
FROM dringe
But adding outlet then subtracting outlet would be redundant. The brackets in your formula would also be redundant as all of your operators are addition/subtraction, could one of your operators be multiplication/division?
you can just add those calculations to your query in something like
(40+50+fieldName*anotherFieldName) AS calculation
and you can even use sub tables like
(40+50+(SELECT fieldName FROM anotherTable WHERE someValue) AS calculation
create view dringe_view as
select (sum(inlet) – sum(outlet) ) +sum(outlet) – sum(dispatched ) as total_summary
from tab
But your claculation can be further simplified (remove outlet - outlet) to (inlet – dispatched)

SQL Server: calculate field data from fields in same table but different set of data

I was looking around and found no solution to this. I´d be glad if someone could help me out here:
I have a table, e.g. that has among others, following columns:
Vehicle_No, Stop1_depTime, Segment_TravelTime, Stop_arrTime, Stop_Sequence
The data might look something like this:
Vehicle_No Stop1_DepTime Segment_TravelTime Stop_Sequence Stop_arrTime
201 13000 60 1
201 13000 45 2
201 13000 120 3
201 13000 4
202 13300 240 1
202 13300 60 2
...
and I need to calculate the arrival time at each stop from the departure time at the first stop and the travel times in between for each vehicle. What I need in this case would look like this:
Vehicle_No Stop1_DepTime Segment_TravelTime Stop_Sequence Stop_arrTime
201 13000 60 1
201 13000 45 2 13060
201 13000 120 3 13105
201 13000 4 13225
202 13300 240 1
202 13300 60 2 13540
...
I have tried to find a solution for some time but was not successful - Thanks for any help you can give me!
Here is the query that still does not work - I am sure I did something wrong with getting the table from the database into this but dont know where. Sorry if this is a really simple error, I have just begun working with MSSQL.
Also, I have implemented the solution provided below and it works. At this point I mainly want to understand what went wrong here to learn about it. If it takes too much time, please do not bother with my question for too long. Otherwise - thanks a lot :)
;WITH recCTE
AS
(
SELECT ZAEHL_2011.dbo.L32.Zaehl_Fahrt_Id, ZAEHL_2011.dbo.L32.PlanAbfahrtStart, ZAEHL_2011.dbo.L32.Fahrzeit, ZAEHL_2011.dbo.L32.Sequenz, ZAEHL_2011.dbo.L32.PlanAbfahrtStart AS Stop_arrTime
FROM ZAEHL_2011.dbo.L32
WHERE ZAEHL_2011.dbo.L32.Sequenz = 1
UNION ALL
SELECT t. ZAEHL_2011.dbo.L32.Zaehl_Fahrt_Id, t. ZAEHL_2011.dbo.L32.PlanAbfahrtStart, t. ZAEHL_2011.dbo.L32.Fahrzeit,t. ZAEHL_2011.dbo.L32.Sequenz, r.Stop_arrTime + r. ZAEHL_2011.dbo.L32.Fahrzeit AS Stop_arrTime
FROM recCTE AS r
JOIN ZAEHL_2011.dbo.L32 AS t
ON t. ZAEHL_2011.dbo.L32.Zaehl_Fahrt_Id = r. ZAEHL_2011.dbo.L32.Zaehl_Fahrt_Id
AND t. ZAEHL_2011.dbo.L32.Sequenz = r. ZAEHL_2011.dbo.L32.Sequenz + 1
)
SELECT ZAEHL_2011.dbo.L32.Zaehl_Fahrt_Id, ZAEHL_2011.dbo.L32.PlanAbfahrtStart, ZAEHL_2011.dbo.L32.Fahrzeit, ZAEHL_2011.dbo.L32.Sequenz, ZAEHL_2011.dbo.L32.PlanAbfahrtStart,
CASE WHEN Stop_arrTime = ZAEHL_2011.dbo.L32.PlanAbfahrtStart THEN NULL ELSE Stop_arrTime END AS Stop_arrTime
FROM recCTE
ORDER BY ZAEHL_2011.dbo.L32.Zaehl_Fahrt_Id, ZAEHL_2011.dbo.L32.Sequenz
A recursive CTE solution - assumes that each Vehicle_No appears in the table only once:
DECLARE #t TABLE
(Vehicle_No INT
,Stop1_DepTime INT
,Segment_TravelTime INT
,Stop_Sequence INT
,Stop_arrTime INT
)
INSERT #t (Vehicle_No,Stop1_DepTime,Segment_TravelTime,Stop_Sequence)
VALUES(201,13000,60,1),
(201,13000,45,2),
(201,13000,120,3),
(201,13000,NULL,4),
(202,13300,240,1),
(202,13300,60,2)
;WITH recCTE
AS
(
SELECT Vehicle_No, Stop1_DepTime, Segment_TravelTime,Stop_Sequence, Stop1_DepTime AS Stop_arrTime
FROM #t
WHERE Stop_Sequence = 1
UNION ALL
SELECT t.Vehicle_No, t.Stop1_DepTime, t.Segment_TravelTime,t.Stop_Sequence, r.Stop_arrTime + r.Segment_TravelTime AS Stop_arrTime
FROM recCTE AS r
JOIN #t AS t
ON t.Vehicle_No = r.Vehicle_No
AND t.Stop_Sequence = r.Stop_Sequence + 1
)
SELECT Vehicle_No, Stop1_DepTime, Segment_TravelTime,Stop_Sequence, Stop1_DepTime,
CASE WHEN Stop_arrTime = Stop1_DepTime THEN NULL ELSE Stop_arrTime END AS Stop_arrTime
FROM recCTE
ORDER BY Vehicle_No, Stop_Sequence
EDIT
Corrected version of OP's query - note that it's not necessary to fully qualify the column names:
;WITH recCTE
AS
(
SELECT Zaehl_Fahrt_Id, PlanAbfahrtStart, Fahrzeit, L32.Sequenz, PlanAbfahrtStart AS Stop_arrTime
FROM ZAEHL_2011.dbo.L32
WHERE Sequenz = 1
UNION ALL
SELECT t.Zaehl_Fahrt_Id, t.PlanAbfahrtStart, t.Fahrzeit,t.Sequenz, r.Stop_arrTime + r.Fahrzeit AS Stop_arrTime
FROM recCTE AS r
JOIN ZAEHL_2011.dbo.L32 AS t
ON t.Zaehl_Fahrt_Id = r.Zaehl_Fahrt_Id
AND t.Sequenz = r.Sequenz + 1
)
SELECT Zaehl_Fahrt_Id, PlanAbfahrtStart, Fahrzeit, Sequenz, PlanAbfahrtStart,
CASE WHEN Stop_arrTime = PlanAbfahrtStart THEN NULL ELSE Stop_arrTime END AS Stop_arrTime
FROM recCTE
ORDER BY Zaehl_Fahrt_Id, Sequenz
I'm quite sure this works:
SELECT a.Vehicle_No, a.Stop1_DepTime,
a.Segment_TravelTime, a.Stop_Sequence, a.Stop1_DepTime +
(SELECT SUM(b.Segment_TravelTime) FROM your_table b
WHERE b.Vehicle_No = a.Vehicle_No AND b.Stop_Sequence < a.Stop_Sequence)
FROM your_table a
ORDER BY a.Vehicle_No