SQL Access 2003 create column if exisit value - sql

I've three table
Product
- ID_Product
UP
- ID_Product
- UP_SUM
DOWN
- ID_Product
- DOWN_SUM
The query on this three tables create a column Total_SUM = [UP_SUM]-[DOWN_SUM]
The problem is that if there is no value in DOWN_SUM there is no result in Total_SUM.
EX.
UP
1 - 2
2 - 4
3 - 2
DOWN
1 - 1
3 - 1
TOTAL_SUM
(1) 1
(2) 4 -> value missing
(3) 1
In the fact i don't get the value for the ID 2.
How can i use statement if not isNULL to get all values in TOTAL_SUM? Actually the SQL Query is:
SELECT
Product.ID_Product,
UP.UP_SUM,
DOWN.DOWN_SUM,
[UP_SUM]-[DOWN_SUM] AS TOTAL_SUM,
FROM (PRODUCT INNER JOIN UP ON Product.ID_Product = UP.ID_Product)
INNER JOIN DOWN ON Product.ID_Product = DOWN.ID_Product;

use the iif condition that will replace null with a value, and use left outer join since normal join is filtering those rows without a match. A left join will keep them with the values NULL
IIF(ISNULL(DOWN.DOWN_SUM),0,DOWN.DOWN_SUM)
SELECT
Product.ID_Product,
IIF(ISNULL(UP.UP_SUM),0,UP.UP_SUM),
IIF(ISNULL(DOWN.DOWN_SUM),0,DOWN.DOWN_SUM),
IIF(ISNULL(UP.UP_SUM),0,UP.UP_SUM)-IIF(ISNULL(DOWN.DOWN_SUM),0,DOWN.DOWN_SUM) AS TOTAL_SUM,
FROM (PRODUCT LEFT OUTER JOIN UP ON Product.ID_Product = UP.ID_Product)
LEFT OUTER JOIN DOWN ON Product.ID_Product = DOWN.ID_Product;

Related

How to find difference between table with multiple conditions

I have exact two tables but some value differences. So I would like to find those differences with condition that if the column value has a difference of more than 10.
For example, all 9 columns have the same values in both tables, but the difference between the values column is 11, so this record is different. If the value difference is 9 so records are the same.
So I wrote this query to get differences:
select *
from test.test m
inner join test.test1 t
on
m.month_date = t.month_date and
m.level_1 = t.level_1 and
m.level_2 = t.level_2 and
m.level_3 = t.level_3 and
m.level_4 = t.level_4 and
m.level_header = t.level_header and
m.unit = t.unit and
m.model_type_id = t.model_type_id and
m.model_version_desc = t.model_version_desc
where m.month_date = '2022-11-01' and abs(m.value - t.value) > 10)
so this returns me all records that all column values are matched but did not pass the value difference condition.
Second, i have full outer join to get all differences
select *
from test.test m
full outer join test.test1 t
on
m.month_date = t.month_date and
m.level_1 = t.level_1 and
m.level_2 = t.level_2 and
m.level_3 = t.level_3 and
m.level_4 = t.level_4 and
m.level_header = t.level_header and
m.unit = t.unit and
m.model_type_id = t.model_type_id and
m.model_version_desc = t.model_version_desc
where m.month_date is null or t.month_date is null and m.month_date = '2022-11-01'
How can I combine the results of these two queries without UNION? I want to have only one query (sub query is acceptable)
Assuming that for a given day, you need to find
rows that match between the tables but exceed the value difference threshold
AND
rows present in either left or right table, that don't have a corresponding row in the other table
select *
from test.test m
full outer join test.test1 t
using (
month_date,
level_1,
level_2,
level_3,
level_4,
level_header,
unit,
model_type_id,
model_version_desc )
where (m.month_date is null
or t.month_date is null
and m.month_date = '2022-11-01' )
or (m.month_date = '2022-11-01' and abs(m.value - t.value) > 10);
Online demo
Since the columns used to join the tables have the same names, you can shorten their list by swapping out the lengthy table1.column1=table2.column1 and... list of pairs for a single USING (month_date,level_1,level_2,level_3,...) (doc). As a bonus, it will avoid listing the matching columns twice in your output, once for the left table, once for the right table.
select *
from (select 1,2,3) as t1(a,b,c)
full outer join
(select 1,2,3) as t2(a,b,c)
on t1.a=t2.a
and t1.b=t2.b
and t1.c=t2.c;
-- a | b | c | a | b | c
-----+---+---+---+---+---
-- 1 | 2 | 3 | 1 | 2 | 3
select *
from (select 1,2,3) as t1(a,b,c)
full outer join
(select 1,2,3) as t2(a,b,c)
using(a,b,c);
-- a | b | c
-----+---+---
-- 1 | 2 | 3
In your first query, you can replace the null values for a specific number. Something like this:
where m.month_date = '2022-11-01' and abs(ISNULL(m.value,-99) - ISNULL(t.value,-99)) > 10)
The above will replace the nulls for -99 (choose an appropriate value for your data), so if you have that m.value is 10 and t.value is null, then should be returned in your first query.

What is outer apply in SQL?

select *
from Kosten_Test a
left join T_Pflege_Parameter pv on pv.Parameterbezeichnung = 'Dummy' and pv.Parametereigenschaft = 'Dummy3'
left join T_Pflege_Parameter pp on pp.Parameterbezeichnung = 'Dummy2' and pp.Parametereigenschaft = a.Herkunft
outer apply( select max(VarianteID) as VarianteID, MerkmalTyp, MerkmalWert
from Test2
where MerkmalTyp = pv.Parameterwert and MerkmalWert = sku
group by MerkmalWert, MerkmalTyp
union
select max(VarianteID) as VarianteID, MerkmalTyp, MerkmalWert
from Testvariante_ASIN_SKU
where MerkmalTyp = pv.Parameterwert and MerkmalWert = a.asin
group by MerkmalWert, MerkmalTyp
) vm
left join (select distinct bundleid from T_Archiv_BundleKomponente) bk on bk.BundleID = vm.VarianteID
Because of the Outer Apply Statement i become always double results. Who can help?
Outer apply is not like a LEFT JOIN. It will apply all the values from the OUTER APPLY Statement to the data joined against.
If your query without the outer apply returns 5 rows and the outer apply query returns 5 rows then the resulting dataset would contain 25 records with each record from the outer apply joined to each row of the other data.
Often times data would be condensed down using aggregations of the values returned from the outer apply query grouped inside of the main query.
Example -
Q1
----
A
B
C
OuterApplyQuery
-----------------
1
2
3
SELECT * FROM Q1 OUTER APPLY (SELECT * FROM OuterApplyQuery) AS X
Result
---------
A 1
A 2
A 3
B 1
B 2
B 3
C 1
C 2
C 3

LEFT OUTER JOIN not always matching

I'm starting with a SQL query with a couple of joins and I'm getting the exact data I expect. This is what the current query is.
SELECT DISTINCT o.OrganizationHierarchyUnitLevelFourCd, o.OrganizationHierarchyUnitLevelThreeNm, o.OrganizationHierarchyUnitLevelFourNm
FROM Lab_Space l
JOIN Worker w ON l.Contact_WWID = w.WWID AND w.Employee_Status_Code = 'A'
JOIN Org_Hierarchy o ON o.OrganizationHierarchyUnitLevelThreeNm IS NOT NULL AND w.Org_Hierarchy_Unit_Cd = o.OrganizationHierarchyUnitCd
ORDER BY o.OrganizationHierarchyUnitLevelThreeNm, o.OrganizationHierarchyUnitLevelFourNm
This ends up with a row like
1234 | Finance | IT
Now I've created a new table, where I'm tracking whether or not I want to include the organization in my output. That table just has two columns, an org ID and a bit field. So I thought I could LEFT OUTER JOIN, since the second table won't have data on all orgs, so I expanded the query to this:
SELECT DISTINCT o.OrganizationHierarchyUnitLevelFourCd, o.OrganizationHierarchyUnitLevelThreeNm, o.OrganizationHierarchyUnitLevelFourNm, v.Include
FROM Lab_Space l
JOIN Worker w ON l.Contact_WWID = w.WWID AND w.Employee_Status_Code = 'A'
JOIN Org_Hierarchy o ON o.OrganizationHierarchyUnitLevelThreeNm IS NOT NULL AND w.Org_Hierarchy_Unit_Cd = o.OrganizationHierarchyUnitCd
LEFT OUTER JOIN Validation_Email_Org_Unit_Inclusion v ON o.OrganizationHierarchyUnitCd = v.OrganizationHierarchyUnitCd
ORDER BY o.OrganizationHierarchyUnitLevelThreeNm, o.OrganizationHierarchyUnitLevelFourNm
The problem I have is now I end up with rows like so:
1234 | Finance | IT | NULL
1234 | Finance | IT | 1
Since the Validation_Email_Org_Unit_Inclusion table includes a 1 for the 1234 org, I would expect to just get a single row with a value of 1, not include the row with NULL.
What have I done wrong?
You output OrganizationHierarchyUnitLevelFourCd but currently join on OrganizationHierarchyUnitCd. Join on the same column you output to get the corresponding value.
SELECT DISTINCT o.OrganizationHierarchyUnitLevelFourCd, ...
...
LEFT OUTER JOIN Validation_Email_Org_Unit_Inclusion v ON o.OrganizationHierarchyUnitLevelFourCd = v.OrganizationHierarchyUnitCd
...

SubQuery inner join with condition

I have two tables (REPORTDETAILS, REPORTITEMS), I want to query one of them to find a max value + 1 between two values, but I also want to find the max value + 1 of another table at the same time.
I am getting the correct value from the first table, but the second value is incorrect because of the condition that I have built in for the first table.
What is the correct way to right this statement?
Thanks for your help as always.
Here is my statement.
SELECT MAX(rd.REPNUMBER) + 1 as REPNUMBER,
MAX(ri.REPITEM) + 1 as REPITEM
FROM REPORTDETAILS rd INNER JOIN REPORTITEMS ri ON rd.REPNUMBER = ri.REPNUMBER
WHERE rd.REPNUMBER BETWEEN 11000000 and 11099999;
You could use CASE within your MAX statement and remove your WHERE criteria:
SELECT MAX(CASE WHEN rd.REPNUMBER BETWEEN 11000000 and 11099999
THEN rd.REPNUMBER END) + 1 as REPNUMBER,
MAX(ri.REPITEM) + 1 as REPITEM
FROM REPORTDETAILS rd
INNER JOIN REPORTITEMS ri ON rd.REPNUMBER = ri.REPNUMBER
Because of the INNER JOIN, this would still only show the max(repitem) based on the matching records between reportdetails and reportitems. If you just want the max(repitem) regardless of the reportdetails, then you could use a CROSS JOIN instead.

Why is this Linq Query returning 3 identical rows from the same SQL view?

I have a simple view defined MSSQL 2008. The view is defined as follows:
SELECT dbo.tblCompany.CompanyID, dbo.tblAccount.Carrier, SUM(ISNULL(dbo.tblLine.LineCharge, 0)) + SUM(ISNULL(dbo.tblLine.FeatureCharge, 0))
+ SUM(ISNULL(dbo.tblLine.AccessCharge, 0)) AS SumOfCharges
FROM dbo.tblCompany LEFT OUTER JOIN
dbo.tblCompany_Location LEFT OUTER JOIN
dbo.tblAccount LEFT OUTER JOIN
dbo.tblLine LEFT OUTER JOIN
dbo.tblBill_Data ON dbo.tblLine.LineID = dbo.tblBill_Data.LineID ON dbo.tblAccount.AccountID = dbo.tblLine.AccountID ON
dbo.tblCompany_Location.LocationID = dbo.tblAccount.LocationID ON dbo.tblCompany.CompanyID = dbo.tblCompany_Location.CompanyID
GROUP BY dbo.tblCompany.CompanyID, dbo.tblAccount.Carrier
Which returns data in the form of:
1 Carrier1 $70.00
1 Carrier2 $100.00
1 Carrier3 $150.00
3 Carrier2 $60.00
....etc
This works fine with an SQL select statement.
I have a VB linq query that just sets a where clause based on the CompanyID.
Dim expenses = From exp In Me.vw_CarrierExpenses _
Where exp.CompanyID = companyId _
Select exp
Return expenses.ToList()
If I filter based on a CompanyID of 1, using the example data above, I get the first row 3 times:
1 Carrier1 $70.00
1 Carrier1 $70.00
1 Carrier1 $70.00
I must be missing something very simple here. It always returns the correct amount of rows but the data is always identical. Thanks.
I keep forgetting that LINQ needs to have a true unique primary key field in query model. I added the following 'fake' primary key to my view by adding:
ROW_NUMBER() OVER (ORDER BY dbo.tblCompany.CompanyID) As 'CarrierExpenseID'
to my view fields and then adding this as my primary key in my view model.