INNER JOIN with 'OR' condition? - inner-join

If have the following coding and the bold marked line is the problem, so it seems to be that's it not possible to use the "OR"-statement within a Inner Join select "ON":
PARAMETERS:
pa_abgrs TYPE vbap-abgrs DEFAULT 'YV0001',
pa_kokrs TYPE kokrs OBLIGATORY DEFAULT '0002',
pa_monat TYPE bis_abgr_m OBLIGATORY,
pa_gjahr TYPE bis_abgr_j OBLIGATORY.
DATA: hlp_datum TYPE sy-datum.
CONSTANTS: comp_nine(20) TYPE c VALUE '09182736455463728190'.
TYPES: BEGIN OF t_tkkaz_tkkar,
kateg TYPE kategorie,
zlnid TYPE dzeilen_id,
koamk TYPE kstar_mask, " Kostenart
zidap TYPE dzeilen_id, " Zeilen-ID akt.pflichtig
zidnf TYPE dzlnid_naf, " Zeilen-ID nicht akt.pfl.
nafpz TYPE naf_prz, " nicht akt.f.%-Satz
END OF t_tkkaz_tkkar.
DATA: lt_tkkaz_tkkar TYPE TABLE OF t_tkkaz_tkkar.
CONCATENATE pa_gjahr pa_gjahr INTO hlp_datum.
TRANSLATE hlp_datum USING comp_nine.
SELECT tkkar~kateg tkkar~zlnid tkkaz~koamk tkkaz~zidap tkkaz~zidnf
tkkaz~nafpz
FROM tkkar
INNER JOIN tkkaz
ON tkkaz~zidnf = tkkar~zlnid
OR tkkaz~zidap = tkkar~zlnid "<==== THIS LINE
INTO TABLE lt_tkkaz_tkkar
WHERE tkkar~kokrs = pa_kokrs
AND tkkar~versa = '000'
AND tkkar~abgsl = pa_abgrs
AND ( tkkar~kateg = 'E'
OR tkkar~kateg = 'K' )
AND tkkaz~kokrs = pa_kokrs
AND tkkaz~versa = '000'
AND tkkaz~abgsl = pa_abgrs.
AND tkkaz~zglab GE hlp_datum.
IF sy-subrc = 0.
cl_demo_output=>display( lt_tkkaz_tkkar )
ENDIf.

It is not supported in ABAP, use UNION instead. It has the same semantics
SELECT FROM tkkar
FIELDS tkkar~kateg tkkar~zlnid tkkaz~koamk tkkaz~zidap tkkaz~zidnf tkkaz~nafpz
INNER JOIN tkkaz
ON tkkar~zlnid = tkkaz~zidnf
WHERE ...
UNION
SELECT FROM tkkar
FIELDS tkkar~kateg tkkar~zlnid tkkaz~koamk tkkaz~zidap tkkaz~zidnf tkkaz~nafpz
INNER JOIN tkkaz
ON tkkar~zlnid = tkkaz~zidap
Also your query is wrong because you missed the key fields while joining. In fact you don't even need UNION here, you can achieve the same putting OR condition into WHERE clause and keeping the other JOIN fields making it more inclusive:
SELECT tkkar~kateg tkkar~zlnid tkkaz~koamk tkkaz~zidap tkkaz~zidnf tkkaz~nafpz
FROM tkkar
INNER JOIN tkkaz
ON tkkar~kokrs = tkkaz~kokrs
AND tkkar~versa = tkkaz~versa
AND tkkar~abgsl = tkkaz~abgsl
INTO TABLE lt_tkkaz_tkkar
WHERE tkkar~kokrs = pa_kokrs
AND tkkar~versa = '000'
AND tkkar~abgsl = pa_abgrs
AND tkkar~kateg IN ('E','K')
AND tkkaz~zglab GE hlp_datum.
AND ( tkkar~zlnid = tkkaz~zidnf OR tkkar~zlnid = tkkaz~zidap ).

Related

Avoid table function in where clause?

I have added table function in the where clause.
select cmp_id, acno_code, sl_type, sl_code, 0 op_Dr, 0 op_cr, 0 tr_Dr, sum(amount) tr_Cr
from vf_finance
where cmp_id =#cmp_id1
and unitcode in (select * from UTILfn_Split( #unit_code,',') )
and stat_code in ('AT','PR' )
--and pc_code in (select * from UTILfn_Split( #sba,',') )
AND DOC_dT >=convert(datetime,#from_date,103) and doc_Dt <= convert(datetime,#to_date,103)
and amount < 0
GROUP BY cmp_id, acno_code, sl_type, sl_code
) as gl
inner join ps_Accmas acc on acc.cmp_id = gl.cmp_id and acc.acno_Code = gl.acno_code
inner join ps_owner o on gl.cmp_id = o.cmp_id
left outer join view_sl_code sl on gl.cmp_id = sl.cmp_id and gl.sl_type = sl.sl_type and gl.sl_Code = sl.sl_Code
inner join ps_slType slt on gl.cmp_id = slt.cmp_id and gl.sl_Type = slt.sl_type
where sl.sl_type in (select * from UTILfn_Split( #sl_type,',') )
and acc.acno_code in(select * from UTILfn_Split( #facno_code,',') )
group by gl.cmp_id, gl.acno_code,gl.sl_code,gl.sl_type,slt.sl_DEsc,acc.acno_DEsc, sl.sl_DEsc, o.owner_name
order by gl.cmp_id, gl.acno_code,gl.sl_code,gl.sl_type
Can anyone please suggest how I can avoid function in where clause?
You may try this. There are some issues in this existing query which I'll point first
First unitcode in (select * from UTILfn_Split( #unit_code,',') here you must use one column name instead of *, although i don't know about your function UTILfn_Split but still mention column name is preferable.
for your query you may use inner join instead of in with function having return type table.
Instead of
sl.sl_type in (select * from UTILfn_Split( #sl_type,',') )
You may try this
yourtble as sl inner join
(select value from UTILfn_Split( #sl_type,',') as t2
on sl.sl_type = t2.[value] ---- here column name with t2 depends on your function,
---what table structure is returning, in your case it is [value]

Converting Oracle Query into T-SQL query using WITH

I have a query from an old database that we converting into T-SQL, but having issues using CTE:
Original Query in Oracle:
select company_name, display_name, active_flag, naic_code, group_number, alien_code, fein,
status_desc, status_detail_desc, due_to_merger_flag, co_code, to_char(status_date, 'MM/DD/YYYY')
Inactive_Date, active_flag from
(select nm.COMPANY_NAME, cmp.recordid_number, orgtp.display_name, cmp.active_flag,
cmp.naic_code, grpnm.group_number, cmp.alien_code, cmp.fein, st.status_desc, stdt.status_detail_desc,
storgjn.due_to_merger_flag, storgjn.co_code, storgjn.status_date, st.active_flag as activestatus,
max(storgjn.status_date) over (partition by cmp.recordid_number, orgtp.display_name) max_status_date
from aip.co_company cmp join aip.CO_NAME nm on cmp.COMPANY_ID = nm.company_id and nm.active_flag = 1
left outer join aip.co_company_group_jn cmpgrpjn on nm.COMPANY_ID = cmpgrpjn.company_id and cmpgrpjn.active_flag = 1
left outer join aip.co_group_name grpnm on cmpgrpjn.group_id = grpnm.group_id and grpnm.active_flag = 1
join aip.co_org org on cmp.COMPANY_ID = org.company_id
join aip.co_org_type orgtp on org.org_type_id = orgtp.org_type_id
join aip.co_status_org_jn storgjn on org.org_id = storgjn.org_id
join aip.co_status_detail stdt on storgjn.status_detail_id = stdt.status_detail_id
join aip.co_status st on stdt.status_id = st.status_id
WHERE cmp.recordid_number = '10632' AND
stdt.status_detail_desc <> 'Record Begin Date')
WHERE status_date = max_status_date
And converting into T-SQl im using:
WITH YOURCTE(WHATEVA) AS
(
SELECT nm.COMPANY_NAME, cmp.recordid_number, orgtp.display_name, cmp.active_flag,
cmp.naic_code, grpnm.group_number, cmp.alien_code, cmp.fein, st.status_desc, stdt.status_detail_desc,
storgjn.due_to_merger_flag, storgjn.co_code, storgjn.status_date, st.active_flag as activestatus,
max(storgjn.status_date) over (partition by cmp.recordid_number, orgtp.display_name) max_status_date
from aip.co_company cmp join aip.CO_NAME nm on cmp.COMPANY_ID = nm.company_id and nm.active_flag = 1
left outer join aip.co_company_group_jn cmpgrpjn on nm.COMPANY_ID = cmpgrpjn.company_id and cmpgrpjn.active_flag = 1
left outer join aip.co_group_name grpnm on cmpgrpjn.group_id = grpnm.group_id and grpnm.active_flag = 1
join aip.co_org org on cmp.COMPANY_ID = org.company_id
join aip.co_org_type orgtp on org.org_type_id = orgtp.org_type_id
join aip.co_status_org_jn storgjn on org.org_id = storgjn.org_id
join aip.co_status_detail stdt on storgjn.status_detail_id = stdt.status_detail_id
join aip.co_status st on stdt.status_id = st.status_id
WHERE cmp.recordid_number = '10632' AND
stdt.status_detail_desc <> 'Record Begin Date'
)
select company_name, display_name, active_flag, naic_code, group_number, alien_code, fein,
status_desc, status_detail_desc, due_to_merger_flag, co_code, CONVERT(VARCHAR(10),status_date,120) AS Inactive_Date,
active_flag
FROM YOURCTE
WHERE status_date = max_status_date
But I get the following error :
Msg 8158, Level 16, State 1, Line 2
'YOURCTE' has more columns than were specified in the column list.
The reason i have more columns in my cte is because I'm using the recordid_number column to bring other data for where conditioning. I will appreciate some help, thank you.
Either replace "WHATEVA" with a complete list of the column aliases you want to use, or remove it and let the original column names stand.
Inherit
;WITH YOURCTE AS
(...
Explicit
;WITH YOURCTE (COMPANY_NAME, recordid_number, ...) AS
(...

How to avoid to duplicate a subquery in a query

I'm running a query that contains the same subquery two times, one used in a inner join condition and the another in a outer join. I'm highlighting the repeated subquery with **. How can I optimize this in order to run only once?
SELECT DISTINCT dbo.tb_contato.Nome, dbo.tb_contato.id_contato, dbo.tb_contato.Sexo, dbo.tb_contato.codigo, dbo.tb_email.email
FROM dbo.tb_contato INNER JOIN
dbo.tb_email ON dbo.tb_contato.id_contato = dbo.tb_email.id_contato INNER JOIN
dbo.tb_empresa ON dbo.tb_empresa.id_empresa = dbo.tb_contato.id_empresa LEFT OUTER JOIN
(SELECT dbo.tb_interacao.IDContato AS id_contato
FROM dbo.tb_interacao INNER JOIN
**(SELECT MAX(IDInteracao) AS IDIntMax, IDPerfilParticipante AS id_perfil_participante, IDProjeto, IDContato
FROM dbo.tb_interacao AS tb_interacao_2
GROUP BY IDPerfilParticipante, IDProjeto, IDContato)** AS IntMax1 ON dbo.tb_interacao.IDInteracao = IntMax1.IDIntMax INNER JOIN
dbo.tb_projeto ON dbo.tb_interacao.IDProjeto = dbo.tb_projeto.id_projeto INNER JOIN
dbo.tb_status_processo ON dbo.tb_interacao.IDStatusProcesso = dbo.tb_status_processo.id_status_processo
WHERE (dbo.tb_projeto.id_projeto = 2057) AND (dbo.tb_interacao.IDPerfilParticipante = 1) AND (dbo.tb_status_processo.id_status_processo = 7) OR
(dbo.tb_projeto.id_projeto = 2057) AND (dbo.tb_interacao.IDPerfilParticipante = 1) AND (dbo.tb_status_processo.id_status_processo = 6) OR
(dbo.tb_interacao.IDPerfilParticipante = 1) AND (dbo.tb_status_processo.id_status_processo = 6) AND (dbo.tb_projeto.id_grupo = 55) OR
(dbo.tb_interacao.IDPerfilParticipante = 1) AND (dbo.tb_status_processo.id_status_processo = 7) AND (dbo.tb_projeto.id_grupo = 55))
AS ConvidadosOut ON dbo.tb_contato.id_contato = ConvidadosOut.id_contato INNER JOIN
(SELECT tb_interacao_1.IDContato AS id_contato
FROM dbo.tb_interacao AS tb_interacao_1 INNER JOIN
**(SELECT MAX(IDInteracao) AS IDIntMax, IDPerfilParticipante AS id_perfil_participante, IDProjeto, IDContato
FROM dbo.tb_interacao AS tb_interacao_3
GROUP BY IDPerfilParticipante, IDProjeto, IDContato)** AS IntMax2 ON tb_interacao_1.IDInteracao = IntMax2.IDIntMax INNER JOIN
dbo.tb_projeto AS tb_projeto_1 ON tb_interacao_1.IDProjeto = tb_projeto_1.id_projeto INNER JOIN
dbo.tb_status_processo AS tb_status_processo_1 ON tb_interacao_1.IDStatusProcesso = tb_status_processo_1.id_status_processo
WHERE (tb_projeto_1.id_projeto = 181) AND (IntMax2.id_perfil_participante = 1) AND (tb_status_processo_1.id_status_processo = 4) OR
(tb_projeto_1.id_projeto = 1581) AND (IntMax2.id_perfil_participante = 1) AND (tb_status_processo_1.id_status_processo = 5) OR
(IntMax2.id_perfil_participante = 1) AND (tb_status_processo_1.id_status_processo = 6) AND (tb_projeto_1.id_grupo = 62)) AS ConvidadosIn ON
dbo.tb_contato.id_contato = ConvidadosIn.id_contato
WHERE (dbo.tb_email.email_visibility = 0 OR
dbo.tb_email.email_visibility IS NULL) AND (dbo.tb_empresa.id_pais = 1) AND (dbo.tb_contato.Fonte <> 'salesloft_orange' AND
dbo.tb_contato.Fonte <> 'salesloft_int_orange' OR
dbo.tb_contato.Fonte IS NULL) AND (dbo.tb_contato.id_contato_visibility = 1 OR
dbo.tb_contato.id_contato_visibility IS NULL) AND (ConvidadosOut.id_contato IS NULL)
I hope you are using SQL server 2005 or later. You can safely try using Common table expressions for the purpose as stated in your question.
Below is an example of script from adventureworks database:
USE AdventureWorks2008R2;
GO
-- Define the CTE expression name and column list.
WITH Sales_CTE (SalesPersonID, SalesOrderID, SalesYear)
AS
-- Define the CTE query.
(
SELECT SalesPersonID, SalesOrderID, YEAR(OrderDate) AS SalesYear
FROM Sales.SalesOrderHeader
WHERE SalesPersonID IS NOT NULL
)
-- Define the outer query referencing the CTE name.
SELECT SalesPersonID, COUNT(SalesOrderID) AS TotalSales, SalesYear
FROM Sales_CTE
GROUP BY SalesYear, SalesPersonID
ORDER BY SalesPersonID, SalesYear;
GO

Query to get values and sum of attributes

I'm trying to write a query but getting an error for finding sum of weights and volume:
SQL Error [8120] [S0001]: Column 'Attribute.attribute_value' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
com.microsoft.sqlserver.jdbc.SQLServerException: Column 'Attribute.attribute_value' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
SELECT
dg.delivery_group_id,
ctr.container_type,
ven.attribute_value AS 'vendor',
carr.attribute_value AS 'carrier',
com.attribute_value AS 'commodity',
conv.attribute_value AS 'conveyance',
stor.attribute_value AS 'store',
SUM(ISNULL(CAST(wgt.attribute_value AS float), 0.0)) AS 'weight',
SUM(ISNULL(CAST(vol.attribute_value AS float), 0.0)) AS 'volume'
FROM (SELECT
pal.container_id AS 'container_id',
pal.container_type AS container_type,
cas.container_id AS 'sub_container_id',
pal.loc_id
FROM container pal
LEFT OUTER JOIN container cas
ON cas.parent_container_id = pal.container_id
AND cas.container_type = 'Case'
WHERE pal.container_type = 'Pallet') AS ctr
INNER JOIN Container_Detail cdtl
ON (ctr.container_id = cdtl.container_id
OR ctr.sub_container_id = cdtl.container_id)
INNER JOIN container_delivery cd
ON cdtl.detail_id = cd.detail_id
INNER JOIN delivery_line dl
ON cd.delivery_line_id = dl.delivery_line_id
INNER JOIN delivery_group dg
ON dl.delivery_group_id = dg.delivery_group_id
INNER JOIN Attribute ven
ON cdtl.attribute_id=ven.attribute_id AND ven.attribute_type='vendor'
INNER JOIN Attribute carr
ON cdtl.attribute_id=carr.attribute_id AND carr.attribute_type='carrier'
INNER JOIN Attribute com
ON cdtl.attribute_id=com.attribute_id AND com.attribute_type='commodity'
INNER JOIN Attribute conv
ON cdtl.attribute_id=conv.attribute_id AND
conv.attribute_type='conveyance'
INNER JOIN Attribute stor
ON cdtl.attribute_id=stor.attribute_id AND stor.attribute_type='store'
INNER JOIN Attribute wgt
ON cdtl.attribute_id=wgt.attribute_id AND wgt.attribute_type='weight'
INNER JOIN Attribute vol
ON cdtl.attribute_id=vol.attribute_id AND vol.attribute_type='volume'
WHERE ctr.container_id = '00007712120038613557'
OR ctr.sub_container_id = '00007712120038613557'
GROUP BY dg.delivery_group_id,
ctr.container_type,ctr.container_id,ctr.sub_container_id,
wgt.attribute_value, vol.attribute_value
Following is my table :
Add all of these to your group by:
group by dg.delivery_group_id,
ctr.container_type,
ven.attribute_value AS,
carr.attribute_value ,
com.attribute_value AS ,
conv.attribute_value ,
stor.attribute_value
SELECT
dg.delivery_group_id,
ctr.container_type,
ven.attribute_value AS 'vendor',
carr.attribute_value AS 'carrier',
com.attribute_value AS 'commodity',
conv.attribute_value AS 'conveyance',
stor.attribute_value AS 'store',
SUM(ISNULL(CAST(wgt.attribute_value AS float), 0.0)) AS 'weight',
SUM(ISNULL(CAST(vol.attribute_value AS float), 0.0)) AS 'volume'
FROM (SELECT pal.container_id AS 'container_id',
pal.container_type AS container_type, cas.container_id AS 'sub_container_id', pal.loc_id FROM container pal LEFT OUTER JOIN container cas ON cas.parent_container_id = pal.container_id
AND cas.container_type = 'Case' WHERE pal.container_type = 'Pallet') AS ctr INNER JOIN Container_Detail cdtl ON (ctr.container_id = cdtl.container_id OR ctr.sub_container_id = cdtl.container_id) INNER JOIN container_delivery cd
ON cdtl.detail_id = cd.detail_id INNER JOIN delivery_line dl ON cd.delivery_line_id = dl.delivery_line_id INNER JOIN delivery_group dg ON dl.delivery_group_id = dg.delivery_group_id INNER JOIN Attribute ven
ON cdtl.attribute_id=ven.attribute_id AND ven.attribute_type='vendor'
INNER JOIN Attribute carr
ON cdtl.attribute_id=carr.attribute_id AND carr.attribute_type='carrier'
INNER JOIN Attribute com
ON cdtl.attribute_id=com.attribute_id AND com.attribute_type='commodity'
INNER JOIN Attribute conv
ON cdtl.attribute_id=conv.attribute_id AND
conv.attribute_type='conveyance'
INNER JOIN Attribute stor
ON cdtl.attribute_id=stor.attribute_id AND stor.attribute_type='store'
INNER JOIN Attribute wgt
ON cdtl.attribute_id=wgt.attribute_id AND wgt.attribute_type='weight'
INNER JOIN Attribute vol
ON cdtl.attribute_id=vol.attribute_id AND vol.attribute_type='volume'
WHERE ctr.container_id = '00007712120038613557'
OR ctr.sub_container_id = '00007712120038613557'
group by
dg.delivery_group_id,
ctr.container_type,
ven.attribute_value AS,
carr.attribute_value ,
com.attribute_value AS ,
conv.attribute_value ,
stor.attribute_value

JOIN codition in SQL Server

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.

Resources