Convert / translate t-sql query to MS Access query - sql

I have a SQL query that I want to use in MS Access, but I can't get it right. Any help would be apprecitated.
select tblKPIData.Id
, tblKPIData.KPI_id
, tblKPIData.Quantity
, tblKPIData.FinancialMonth
, tblKPIData.FinancialYear
, tblKPIData.ImportTimestamp
, tblDashboadKPI.Dashboard_Id
from (
select tblKPIData.kpi_id,
max(tblKPIData.ImportTimestamp) as ImportTimestamp
from tblKPIData
group by tblKPIData.KPI_id
)
as b
inner join tblKPIData
on tblKPIData.KPI_id = b.KPI_id
and tblKPIData.ImportTimestamp = b.ImportTimestamp
right join tblDashboadKPI
on tblDashboadKPI.KPI_Id = tblKPIData.KPI_id
where FinancialMonth = 'nov'
and FinancialYear = 2016
and tblDashboadKPI.Dashboard_Id = 5
order by tblKPIData.Id
,tblKPIData.KPI_id

If your query currently works, I would suggest:
select kp.Id, kp.KPI_id, kp.Quantity, kp.FinancialMonth,
kp.FinancialYear, kp.ImportTimestamp,
d.Dashboard_Id
from ((select tblKPIData.kpi_id,
max(tblKPIData.ImportTimestamp) as ImportTimestamp
from tblKPIData
group by tblKPIData.KPI_id
) as b inner join
tblKPIData as kp
on kp.KPI_id = b.KPI_id and kp.ImportTimestamp = b.ImportTimestamp
) right join
tblDashboadKPI as d
on d.KPI_Id = kp.KPI_id
where FinancialMonth = "nov" and FinancialYear = 2016 and
d.Dashboard_Id = 5
order by kp.Id, kp.KPI_id;
Changes:
JOINs need to have additional parentheses
Strings uses double quots
I introduced table aliases as well, to simplify the query

I think I have the solution:
SELECT tblKPIData.Id
, tblKPIData.KPI_id
, tblKPIData.Quantity
, tblKPIData.FinancialMonth
, tblKPIData.FinancialYear
, tblKPIData.ImportTimestamp
, tblKPIData.Type
, tblDashboadKPI.Dashboard_Id
FROM tblDashboadKPI
INNER JOIN tblKPIData
ON tblDashboadKPI.KPI_Id = tblKPIData.KPI_id
WHERE (((tblKPIData.FinancialMonth)="nov")
AND ((tblKPIData.FinancialYear)=2016)
AND ((tblKPIData.ImportTimestamp)=(select max(d2.ImportTimestamp)
from tblKPIData as d2
where d2.KPI_Id = tblKPIData.KPI_Id))
AND ((tblDashboadKPI.Dashboard_Id)=5));
Thanx for your help!

Related

converting a sql query without sub query

Is there a way to convert this query into one without having the subquery in where clause?
select distinct
ie.install_id
, ie.sp_id
, ie.device_config_id
from d1_sp sp
inner join install_evt ie
on ie.sp_id = sp.sp_id
where ie.install_dttm = (select max(iemax.install_dttm)
from install_evt iemax
where iemax.sp_id = sp.sp_id)
select distinct
ie.install_id
, ie.sp_id
, ie.device_config_id
, max(ie.install_dttm)
from d1_sp sp
inner join install_evt ie
on ie.sp_id = sp.sp_id
group by ie.install_id, ie.sp_id, ie.device_config_id
if you need additional grouping you can use an order by

Which query is faster to execute

Following are two options to query CTE and NFSE data. Pls advise !
A similar approach may have to be used in many places.
I would like you to verify them and suggest, if there are better options.
Option 1: Query CTE with all necessary joins UNION with query on NFSe with all necessary joins
SELECT DISTINCT 'CTE' as docTypeID
, cte.isqn_mstr_cd as ctePk
, cte.ct_e_cd
, cter.stat_desc
, awb.CREATE_DT
, awb.AWB_NBR
, awb.SHPR_NM
, awbs.DEST_LOC_CD
, nfe.NT_FSCL_CD
, nfe.FSCL_DOC_NBR
FROM cte_identity_master cte
INNER JOIN cte_response_detail cter ON (cte.isqn_mstr_cd = cter.isqn_mstr_cd)
LEFT JOIN match_ref_awb mawb ON (cte.isqn_ref_cd = mawb.isqn_mstr_cd)
LEFT JOIN awb_cust_master awb ON (mawb.awb_nbr = awb.awb_nbr)
LEFT JOIN awb_shipment_detail awbs ON (awb.awb_nbr = awbs.awb_nbr)
LEFT JOIN match_ref_nfe mnfe ON (cte.isqn_ref_cd = mnfe.isqn_mstr_cd)
LEFT JOIN nfe_identity_master nfe ON (mnfe.nt_fscl_cd = nfe.nt_fscl_cd)
UNION
SELECT DISTINCT 'NFSE' as docTypeID
, nfse.isqn_mstr_cd as nfsePk
, nfse.rp_s_id
, nfser.stat_desc
, awb.CREATE_DT
, awb.AWB_NBR
, awb.SHPR_NM
, awbs.DEST_LOC_CD
, nfe.NT_FSCL_CD
, nfe.FSCL_DOC_NBR
FROM nfse_request_detail nfse
INNER JOIN nfse_response_detail nfser ON (nfse.isqn_mstr_cd = nfser.isqn_mstr_cd)
LEFT JOIN match_ref_awb mawb ON (nfse.isqn_ref_cd = mawb.isqn_mstr_cd)
LEFT JOIN awb_cust_master awb ON (mawb.awb_nbr = awb.awb_nbr)
LEFT JOIN awb_shipment_detail awbs ON (awb.awb_nbr = awbs.awb_nbr)
LEFT JOIN match_ref_nfe mnfe ON (nfse.isqn_ref_cd = mnfe.isqn_mstr_cd)
LEFT JOIN nfe_identity_master nfe ON (mnfe.nt_fscl_cd = nfe.nt_fscl_cd)
;
Option 2: Use Union of CTe and NFSe first and then apply joins with other tables
SELECT ctnf.*
, awb.CREATE_DT
, awb.AWB_NBR
, awb.SHPR_NM
, awbs.DEST_LOC_CD
, nfe.NT_FSCL_CD
, nfe.FSCL_DOC_NBR
FROM (
SELECT DISTINCT 'CTE' as docTypeID
, cte.isqn_mstr_cd as docPk
, cte.ct_e_cd as docNbr
, cter.stat_desc as docStat
, cte.isqn_ref_cd as matchRef
FROM cte_identity_master cte
INNER JOIN cte_response_detail cter ON (cte.isqn_mstr_cd = cter.isqn_mstr_cd)
UNION
SELECT DISTINCT 'NFSE' as docTypeID
, nfse.isqn_mstr_cd as nfsePk
, nfse.rp_s_id
, nfser.stat_desc
, nfse.isqn_ref_cd
FROM nfse_request_detail nfse
INNER JOIN nfse_response_detail nfser ON (nfse.isqn_mstr_cd = nfser.isqn_mstr_cd)
) ctnf
LEFT JOIN match_ref_awb mawb ON (ctnf.matchRef = mawb.isqn_mstr_cd)
LEFT JOIN awb_cust_master awb ON (mawb.awb_nbr = awb.awb_nbr)
LEFT JOIN awb_shipment_detail awbs ON (awb.awb_nbr = awbs.awb_nbr)
LEFT JOIN match_ref_nfe mnfe ON (ctnf.matchRef = mnfe.isqn_mstr_cd)
LEFT JOIN nfe_identity_master nfe ON (mnfe.nt_fscl_cd = nfe.nt_fscl_cd)
;
Both approaches of the above will have following Where Clause:
WHERE lower(cte.sttn_cd) = lower(:stationId)
and (:documentType is null or lower(:documentType) = 'cte')
and (:shipperName is null or lower(awb.shipperNm) like lower(concat(concat('%',:shipperName),'%')))
and (:awbCreated is null or to_char(awb.createDt, 'MM-DD-YYYY') = :awbCreated)
and (:awbNumber is null or m2.awbNbr like concat(concat('%',:awbNumber),'%'))
and (:serviceType = 0 or awbs.baseServiceCd = :serviceType)
and (:commitmentDate is null or awbs.commitmentDate = :commitmentDate)
and (:ursa is null or lower(awbs.ursaCd) like lower(concat(concat('%',:ursa),'%')))
and (:destLocationId is null or lower(awbs.destLocCd) like lower(concat(concat('%',:destLocationId),'%')))
and (:nfeNumber is null or nfe.fiscalDocumentNumber like concat(concat('%',:nfeNumber),'%'))
PLEASE SUGGEST - Output of these two approaches to get data which one will be better to fix at Java End to retrieve the data.
Any help will be greatly appreciated. Also suggest if there is any other better query apart from these two!

Major issues with a query

I have a query
SELECT
ZEML.ICC_CODE AS ICC_CODE
,SUM(CS.TOT_HOURS) AS TOT_HOURS
,SUM(CS.NUM_INCIDENT_ALL) AS NUM_INCIDENTS
,(VALUE(FLOAT(SUM(CS.NUM_INCIDENT_ALL)) * 200000 / SUM(TOT_HOURS)
,0)) AS INC_RATE
FROM TR.CLAIMS_SUMM CS
INNER JOIN TR.LOCATION_MASTER LM
ON LM.LOCATION = CS.LOCATION
AND CS.LOCATION < '900'
LEFT JOIN TR.LOCATION_ASSIGNMENTS DISTRICT
ON DISTRICT.LOCATION = LM.LOCATION
AND DISTRICT.ASSIGNMENT_TYPE = 'District'
LEFT JOIN TR.LOCATION_ASSIGNMENTS TERRITORY
ON TERRITORY.LOCATION = LM.LOCATION
AND TERRITORY.ASSIGNMENT_TYPE = 'Territory'
LEFT JOIN TR.EMPL_CLAIMS ZEML
ON CS.LOCATION = ZEML.LOCATION
AND ZEML.TYPE = 'WC'
AND ZEML.STATUS <> 'V'
AND ZEML.CLAIM_ACTION NOT IN ('D','F','I','H')
WHERE CS.DW_DATE BETWEEN '01/01/2014'
AND '05/31/2014'
AND (MONTH(ZEML.DATE_OF_INCIDENT) = MONTH(CS.DW_DATE)
AND YEAR(ZEML.DATE_OF_INCIDENT) = YEAR(CS.DW_DATE))
GROUP BY ZEML.ICC_CODE
UNION
SELECT
'OTHER' AS ICC_CODE
, 0 AS TOT_HOURS
, 0 AS NUM_INCIDENTS
, 0 AS INC_RATE
FROM SYSIBM.SYSDUMMY1
WHERE 1 = 1
ORDER BY 1
in my union where I made an other I want to select everything else from the tr.empl_claims table and store it in the other from the union because this is what I have many other ICC codes without incidents on them and I am doing calculations on our incident rate and hourse based off of all the data but my query right now is only selecting the ones that currently is having incidents which is throwing off my calculations.
From your use of FROM SYSIBM.SYSDUMMY1 I believe you are using DB2 database. If yes, you can use CTE (common table expression) to achieve the desired result like
WITH cte1 AS
(
SELECT
ZEML.ICC_CODE AS ICC_CODE
,SUM(CS.TOT_HOURS) AS TOT_HOURS
,SUM(CS.NUM_INCIDENT_ALL) AS NUM_INCIDENTS
,(VALUE(FLOAT(SUM(CS.NUM_INCIDENT_ALL)) * 200000 / SUM(TOT_HOURS)
,0)) AS INC_RATE
FROM TR.CLAIMS_SUMM CS
... <rest of the code> ...
)
select * from cte1
UNION ALL
SELECT
ICC_CODE
, 0 AS TOT_HOURS
, 0 AS NUM_INCIDENTS
, 0 AS INC_RATE
FROM TR.EMPL_CLAIMS
WHERE ICC_CODE NOT IN
(
SELECT distinct ICC_CODE
FROM cte1
)
ORDER BY 1
SideNote: You are joining the same table LOCATION_ASSIGNMENTS twice (as below) which is not needed.
LEFT JOIN TR.LOCATION_ASSIGNMENTS DISTRICT
ON DISTRICT.LOCATION = LM.LOCATION
AND DISTRICT.ASSIGNMENT_TYPE = 'District'
LEFT JOIN TR.LOCATION_ASSIGNMENTS TERRITORY
ON TERRITORY.LOCATION = LM.LOCATION
AND TERRITORY.ASSIGNMENT_TYPE = 'Territory'
This can be transformed to below using a IN operator
LEFT JOIN TR.LOCATION_ASSIGNMENTS DISTRICT
ON DISTRICT.LOCATION = LM.LOCATION
AND DISTRICT.ASSIGNMENT_TYPE IN ('District', 'Territory')
See more about Common Table Expression in DB2 Here.
Hope this helps.

SQL INNER JOIN DISTINCT with max function

I have the tables tbMeasurement and tbPatientMeasurement .
tbMeasurement
MeasurementIDP
MeasurementName
tbPatientMeasurement
PatientMeasurementIDP
MeasurementIDF
MeasurementValue
Taken (Datetime)
When doing the following query:
SELECT DISTINCT dbo.tbMeasurement.MeasurementName
, dbo.tbPatientMeasurement.MeasurementValue
, dbo.tbPatientMeasurement.Taken
FROM dbo.tbMeasurement
INNER JOIN dbo.tbPatientMeasurement
ON dbo.tbMeasurement.MeasurementIDP = dbo.tbPatientMeasurement.MeasurementIDF
This returns a double entry of one of the MeasurementName.
and i also want MeasurementName,MeasurementValue by max Taken(datetime).
Try this one -
SELECT DISTINCT
m.MeasurementName
, p2.MeasurementValue
, p2.Taken
FROM dbo.tbMeasurement m
JOIN (
SELECT
p.MeasurementValue
, Taken = MAX(p.Taken)
FROM dbo.tbPatientMeasurement p
GROUP BY m.MeasurementName, p.MeasurementValue
) p2 ON m.MeasurementIDP = p2.MeasurementIDF
SELECT
m.MeasurementName
, p.MeasurementValue
, a.Taken
FROM dbo.tbMeasurement m
INNER JOIN dbo.tbPatientMeasurement p ON m.MeasurementIDP = p.MeasurementIDF
INNER JOIN
(
select MeasurementIDF,MAX(Taken) as taken
from tbPatientMeasurement
group by MeasurementIDF
) a on a.MeasurementIDF=p.MeasurementIDF and a.taken=p.Taken

PIVOT'ing in SQL server

I have the below query whcih I want to pivot.
SELECT
tbl_track_empHours.track_empHours_hours as emphours
,tbl_track_empHours.track_empHours_date as empHDate
, tbl_track_jobInfo.track_jobInfo_jobNum AS JobNum
, tbl_track_jobInfo.track_jobInfo_ProjName AS ProjName
, tbl_track_jobCodes.track_jobCode_jc AS jc
, tbl_track_jobCodes.track_jobCode_id_pk AS ts_JobCodeID
, tbl_track_empHours.track_empHours_main_usr_id_fk
, tbl_track_jobInfo.track_jobInfo_id_pk AS ts_JobID
FROM tbl_track_empHours INNER JOIN
tbl_track_jobInfo ON tbl_track_empHours.track_empHours_jobinfo_id_fk=tbl_track_jobInfo.track_jobInfo_id_pk INNER JOIN
tbl_track_jobCodes ON tbl_track_empHours.track_empHours_jobCode_id_fk = tbl_track_jobCodes.track_jobCode_id_pk
WHERE (tbl_track_empHours.track_empHours_main_usr_id_fk = '268')
AND (tbl_track_empHours.track_empHours_date BETWEEN '05/09/2011' AND '05/15/2011')
ORDER BY tbl_track_jobInfo.track_jobInfo_jobNum, tbl_track_jobCodes.track_jobCode_jc!
The result looks like this.
I want to pivot the column 'emphours' against the rest of the columns. The pivoted columns should have the dates between '05/09/2011' AND '05/15/2011'
Any help appreciated.
Pivot result
This could help you for sure.
Select * from (Select JobNum,ProjName,jc,ts_JobCodeID,mainUsrFk,ts_JobID,
[05/09/2011] as col1,[05/11/2011] as col2,[05/12/2011] as col3,
[05/13/2011] as col4,[05/14/2011] as col5,[05/15/2011] as col6,[05/10/2011] as col7 from (
SELECT
tbl_track_empHours.track_empHours_hours
,tbl_track_empHours.track_empHours_date
, tbl_track_jobInfo.track_jobInfo_jobNum AS JobNum
, tbl_track_jobInfo.track_jobInfo_ProjName AS ProjName
, tbl_track_jobCodes.track_jobCode_jc AS jc
, tbl_track_jobCodes.track_jobCode_id_pk AS ts_JobCodeID
, tbl_track_empHours.track_empHours_main_usr_id_fk as mainUsrFk
, tbl_track_jobInfo.track_jobInfo_id_pk AS ts_JobID
FROM tbl_track_empHours INNER JOIN
tbl_track_jobInfo ON tbl_track_empHours.track_empHours_jobinfo_id_fk = tbl_track_jobInfo.track_jobInfo_id_pk INNER JOIN
tbl_track_jobCodes ON tbl_track_empHours.track_empHours_jobCode_id_fk = tbl_track_jobCodes.track_jobCode_id_pk
WHERE (tbl_track_empHours.track_empHours_main_usr_id_fk = '268')
AND (tbl_track_empHours.track_empHours_date BETWEEN '5/09/2011' AND '5/15/2011')
) o
PIVOT( SUM(o.track_empHours_hours)
FOR o.track_empHours_date in ([05/09/2011],[05/10/2011],[05/11/2011],[05/12/2011],
[05/13/2011],[05/14/2011],[05/15/2011]))p ) as a