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
Related
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.
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
...
I have a SQL Query:
Select Top 3 dbo.FN_GetLRExpenseAmount(VendorBillID,LRNo,PM.PickupRunsheetNo)
From PickupRunsheetMaster PM Left Outer Join
PickupRunsheetDetail PRD
ON PM.PickupRunsheetNo = PRD.PickupRunsheetNo
Where ISNULL(VendorBillID,0) > 0
Output:
601.90
14.56
145.62
When I sum the return value of function dbo.FN_GetLRExpenseAmount(VendorBillID,LRNo,PM.PickupRunsheetNo) throuth below query then it does not return any value
Select Top 3 SUM(dbo.FN_GetLRExpenseAmount(VendorBillID, LRNo, PM.PickupRunsheetNo))
From PickupRunsheetMaster PM Left Outer Join
PickupRunsheetDetail PRD
ON PM.PickupRunsheetNo = PRD.PickupRunsheetNo
Where ISNULL(VendorBillID,0) > 0
The queries are not the same. The TOP 3 does nothing in the second query, because it is an aggregation query that returns only one row.
For an equivalent query, use a subquery or CTE:
select sum(val) as sum_3
from (Select Top 3 dbo.FN_GetLRExpenseAmount(VendorBillID, LRNo, PM.PickupRunsheetNo) as val
From PickupRunsheetMaster PM Left Outer Join
PickupRunsheetDetail PRD
ON PM.PickupRunsheetNo = PRD.PickupRunsheetNo
Where ISNULL(VendorBillID,0) > 0
) x
TOP 3 SUM gives you this result. To get the sum value of the top 3 records you want, Create a subquery:
SELECT
SUM(A.Expense)
FROM
(
Select Top 3 dbo.FN_GetLRExpenseAmount(VendorBillID, LRNo, PM.PickupRunsheetNo) AS [Expense]
From PickupRunsheetMaster PM Left Outer Join
PickupRunsheetDetail PRD
ON PM.PickupRunsheetNo = PRD.PickupRunsheetNo
Where ISNULL(VendorBillID,0) > 0
) AS A
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;
How can I make something like this
select
a.atest, a.btest, a.ctest, b.atest, b.btest
from
test.dbo.rm a(nolock)
cross apply
wat.dbo.ar(a.atest,a.btest) b
where
a.rmd = 9 and a.btest > 0
alter function ar(#atest varchar(25), #btest numeric(19,5))
returns table as
return
(
select atest, btest from test.dbo.rm (nolock)
where rmd = 1 and atest=#atest and btest=#btest
)
with delete statement or update. I don't want to make duplicates so after I choose one b.atest I want to delete the record with b.atest or set b.btest to 0. This query is working on table that contain about 5-10 million of records.. so it must be quick.
Use query without function:
select a.atest,a.btest,a.ctest,b.atest,b.btest
from test.dbo.rm a(nolock)
cross apply (
select top 1 atest, btest
from test.dbo.rm t (nolock)
where t.rmd = 1 and t.atest=a.atest and t.btest=a.btest
)b
where a.rmd = 9 and a.btest > 0
You can also use Left join instead of cross apply:
select *
from (
select a.atest,a.btest,a.ctest,b.atest,b.btest,
row_number() over ( partition by b.atest, b.btest order by b.id) as row
from test.dbo.rm a(nolock)
LEFT JOIN test.dbo.rm b ON b.rmd = 1 and b.atest=a.atest and b.btest=a.btest
where a.rmd = 9 and a.btest > 0
)z
where z.row = 1