I'm using SQL Server. I've 3 tables :
tblUser
tblAudit
tblEnum
The tblAudit has got 4 columns :
nUserId, nID: These two columns point to the tblUser
vFromValue, vToValue: These two columns point to the tblEnum
Now, I need to show the actual values from the tblUser and tblEnum based on the IDs present in the tblAudit table.
The query that I have written looks something like this :
SELECT A.aEventID,
U.tName AS MakerChecker,
U2.tName AS OnUser,
VLE.tDisplayName AS FromValue,
VLE2.tDisplayName AS ToValue,
A.dChangeTime AS Timestamp
FROM tblAudit A INNER JOIN tblUser U ON A.nUserId = U.aUserId
INNER JOIN tblUser U2 ON A.nID = U2.aUserId
INNER JOIN tblEnum VLE ON A.vFromValue = VLE.nIndex OR (A.vFromValue IS NULL)
INNER JOIN tblEnum VLE2 ON A.vToValue = VLE2.nIndex OR (A.vToValue IS NULL)
Because the values in the Audit table is null for the columns vFromValue and vToValue for some rows, those values are not coming as NULL but the previous value.
How can I display the null values intact by changing the above query? Please help.
Since the tblAudit.vFromValue and tblAudit.vToValue have NULLs, try this:
SELECT A.aEventID,
U.tName AS MakerChecker,
U2.tName AS OnUser,
VLE.tDisplayName AS FromValue,
VLE2.tDisplayName AS ToValue,
A.dChangeTime AS Timestamp
FROM
( SELECT aEventID, nUserId, nID, dChangeTime
, COALESCE(vFromValue, -9999) AS vFromValue --- some non-existent
, COALESCE(vToValue, -999) AS vToValue --- value
FROM tblAudit
) AS A
INNER JOIN tblUser U
ON A.nUserId = U.aUserId
INNER JOIN tblUser U2
ON A.nID = U2.aUserId
LEFT JOIN tblEnum VLE
ON A.vFromValue = VLE.nIndex
LEFT JOIN tblEnum VLE2
ON A.vToValue = VLE2.nIndex
or this:
SELECT A.aEventID,
U.tName AS MakerChecker,
U2.tName AS OnUser,
( SELECT VLE.tDisplayName
FROM tblEnum VLE
WHERE A.vFromValue = VLE.nIndex
) AS FromValue,
( SELECT VLE2.tDisplayName
FROM tblEnum VLE2
WHERE A.vToValue = VLE.nIndex
) AS ToValue,
A.dChangeTime AS Timestamp
FROM tblAudit AS A
INNER JOIN tblUser U
ON A.nUserId = U.aUserId
INNER JOIN tblUser U2
ON A.nID = U2.aUserId
If I understand your question-- try use LEFT JOIN for your two last rows (and delete conditions after OR).
Related
I have 3 tables in that 2 tables are master table and 3rd is transaction table. i need to get count from transaction table for each value in other two table without loosing rows in mater table
i need result like below
Table layout for understanding
This is the code i have tried,
select s.status_name, e.machine_group_name, qty = COALESCE(COUNT(e.id),0)
from tbl_status s
left outer JOIN tbl_transaction as e ON e.status_name = s.status_name
group by e.machine_group_name, s.status_name
This is solution i have figured:
select m.machine_group_name, s.status_name, qty = COUNT(e.id) from
tbl_machine_group as m
cross join tbl_status as s
left outer join tbl_transaction as e on e.status_name = s.status_name
and e.machine_group_name = m.machine_group_name
group by m.machine_group_name, s.status_name
order by machine_group_name
select
MC_Group_Name
,Status_Name
,count(1) as [Count of Transaction]
from
tbl_Transaction tbl_3
left join tbl_Machine_Group tbl_1
on tbl_3.MC_Group_Name = tbl_1.MC_Group_Name
left join tbl_Status tbl_2
on tbl_3.Status_Name = tbl_2.Status_Name
group by
MC_Group_Name
,Status_Name
hello there i wanted to remove redundant data from the multiple join queries. but i'm getting duplicate data after running this query.
INVOICE TABLE
INVOICE_DETAILS TABLE
JOB_DETAILS TABLE
IMP_BILLING_TERMS_DETAILS TABLE
RESULT AFTER RUN THIS QUERY
SELECT DISTINCT
INV.bill_ID,
INV.Bill_No,
Agency_Charges = (SELECT DISTINCT IBTD.Amount_Paid
FROM Invoice_Details INV_details inner join Imp_Billing_Terms_Details IBTD on INV_details.Billing_Term_ID_Auto = IBTD.Billing_Terms_ID_Auto AND IBTD.Billing_Term_ID = '1033'
WHERE INV_details.Invoice_ID = INV.bill_ID)
FROM Invoice INV inner JOIN Job_Details JD on INV.Job_ID = JD.Job_ID
WHERE JD.Job_No is not null and INV.Bill_No is not null and JD.Gen_Bill = 'Y' AND JD.Company_ID='2'
I have a table with values en date/timstamps. This table is dbo.meterdata.value. The output that i want to see is as followed: The latest date/timestamp (Max) but only the ones where te latest date/timestamp is last week. My Query is:
SELECT dbo.meter.DataImportCode
,dbo.meter.NAME
,dbo.company.NAME
,dbo.meter.MeterNumber
,MAX(dbo.meterdata.RoundedTimeStamp) AS 'laatste datum'
,dbo.MeterOperator.Description
,dbo.meter.CumulativeReadings
FROM dbo.meter
LEFT OUTER JOIN DBO.MeterData ON dbo.meter.MeterID = dbo.meterdata.MeterID
JOIN DBO.Site ON dbo.meter.SiteID = dbo.site.SiteID
JOIN DBO.Company ON dbo.site.CompanyID = dbo.company.CompanyID
JOIN DBO.MeterOperator ON dbo.meter.MeterOperatorID = dbo.MeterOperator.MeterOperatorID
--WHERE (select (dbo.meterdata.roundedtimestamp) from dbo.MeterData) < DateAdd(DD,-7,GETDATE() )
AND dbo.meterdata.RoundedTimeStamp IS NOT NULL
GROUP BY dbo.meter.DataImportCode
,dbo.company.NAME
,dbo.meter.NAME
,dbo.meter.MeterNumber
,dbo.MeterOperator.Description
,dbo.meter.CumulativeReadings
Example of the unfilterd result:
Example
Thank you for help and support
Try the following:
select dbo.meter.DataImportCode, dbo.meter.Name, dbo.company.Name, dbo.meter.MeterNumber,MAX(dbo.meterdata.RoundedTimeStamp) AS 'laatste datum', dbo.MeterOperator.Description, dbo.meter.CumulativeReadings
from dbo.meter
LEFT OUTER JOIN DBO.MeterData ON dbo.meter.MeterID = dbo.meterdata.MeterID
JOIN DBO.Site on dbo.meter.SiteID = dbo.site.SiteID
JOIN DBO.Company on dbo.site.CompanyID = dbo.company.CompanyID
JOIN DBO.MeterOperator on dbo.meter.MeterOperatorID = dbo.MeterOperator.MeterOperatorID
--WHERE (select (dbo.meterdata.roundedtimestamp) from dbo.MeterData) < DateAdd(DD,-7,GETDATE() )
--AND dbo.meterdata.RoundedTimeStamp is not null
GROUP BY dbo.meter.DataImportCode, dbo.company.name, dbo.meter.Name, dbo.meter.MeterNumber, dbo.MeterOperator.Description, dbo.meter.CumulativeReadings
HAVING [laatste datum] < DateAdd(day,-7,GETDATE())
If I understood you right, what you want to do is filter out the data after it has been grouped. This is done using the HAVING clause of the SELECT statement, as the above query depicts.
WITH KPILibHier (kpilib_code,parent_code,kpi_name, depth, iscategory)
AS ( SELECT K.kpilib_code, K.parent_code, K.kpi_name_en, K.kpi_depth, K.iscategory
FROM TPMDPERIODKPILIB K
INNER JOIN TPMDPERIODKPI PK ON PK.period_code = K.period_code
UNION ALL
SELECT A.kpilib_code, A.parent_code, A.kpi_name_en, A.kpi_depth, A.iscategory
FROM TPMDPERIODKPILIB A
INNER JOIN KPILibHier AS B ON A.kpilib_code = B.parent_code )
SELECT DISTINCT Z.kpi_name AS libname, Z.kpilib_code AS libcode,
Z.parent_code AS pcode, Z.depth, Z.iscategory, PK.target
FROM KPILibHier Z
LEFT JOIN TPMDPERIODKPILIB KPI
ON KPI.kpilib_code = Z.kpilib_code
LEFT JOIN TPMDPERIODKPI PK
ON PK.period_code = KPI.period_code
ORDER BY Z.depth, Z.kpi_name
This is my code.
I could run it in SQL Server,
But now i have to use Mariadb,
and Mariadb doesn't use "WITH AS".
So is there any other way to change this code for the same result?
As we can see, there's "INNER JOIN KPILibHier" too inside the CTE,
So I couldn't make ordinary subquery as usual.
Just moving the contents of the CTE to a derived table should provide something usable. Something like;
SELECT DISTINCT Z.kpi_name AS libname, Z.kpilib_code AS libcode,
Z.parent_code AS pcode, Z.depth, Z.iscategory, PK.target
FROM
( SELECT K.kpilib_code, K.parent_code, K.kpi_name_en AS kpi_name, K.kpi_depth AS depth, K.iscategory
FROM TPMDPERIODKPILIB K
INNER JOIN TPMDPERIODKPI PK ON PK.period_code = K.period_code
UNION ALL
SELECT A.kpilib_code, A.parent_code, A.kpi_name_en, A.kpi_depth, A.iscategory
FROM TPMDPERIODKPILIB A
) z
INNER JOIN z AS B ON A.kpilib_code = B.parent_code
LEFT JOIN TPMDPERIODKPILIB KPI
ON KPI.kpilib_code = Z.kpilib_code
LEFT JOIN TPMDPERIODKPI PK
ON PK.period_code = KPI.period_code
ORDER BY Z.depth, Z.kpi_name
After applying join condition on two tables I want records which is maximum among records of left table
My query
SELECT a1.*,
t.*,
( a1.trnratefrom - t.trnratefrom )AS minrate,
( a1.trnrateto - t.trnrateto ) AS maxrate
FROM (SELECT a.srno,
trndate,
b.trnsrno,
Upper(Rtrim(Ltrim(b.trnstate))) AS trnstate,
Upper(Rtrim(Ltrim(b.trnarea))) AS trnarea,
Upper(Rtrim(Ltrim(b.trnquality))) AS trnquality,
Upper(Rtrim(Ltrim(b.trnlength))) AS trnlength,
Upper(Rtrim(Ltrim(b.trnunit))) AS trnunit,
b.trnratefrom,
b.trnrateto,
a.remark,
entdate
FROM mstprodrates a
INNER JOIN trnprodrates b
ON a.srno = b.srno)a1
INNER JOIN (SELECT c.srno,
trndate,
d.trnsrno,
Upper(Rtrim(Ltrim(d.trnstate))) AS trnstate,
Upper(Rtrim(Ltrim(d.trnarea))) AS trnarea,
Upper(Rtrim(Ltrim(d.trnquality))) AS trnquality,
Upper(Rtrim(Ltrim(d.trnlength))) AS trnlength,
Upper(Rtrim(Ltrim(d.trnunit))) AS trnunit,
d.trnratefrom,
d.trnrateto,
c.remark,
entdate
FROM mstprodrates c
INNER JOIN trnprodrates d
ON c.srno = d.srno) AS t
ON a1.trnstate = t.trnstate
AND a1.trnquality = t.trnquality
AND a1.trnunit = t.trnunit
AND a1.trnlength = t.trnlength
AND a1.trnarea = t.trnarea
AND a1.remark = t.remark
WHERE t.srno = (SELECT MAX(srno)
FROM a1
WHERE srno < a1.srno)
If you mean to say,
you want Records exist in Left table but not in right then use LEFT OUTER JOIN.