I tried this query but it doesn't work, ORA-00904 error.
SELECT
C.BUSINESS_UNIT
,COALESCE(L.CHILD_CONTR_ID
,L.PARENT_CONTR_ID) AS CONTRAT
, C.BILL_TO_CUST_ID
FROM C_LIE_VW L
,CONTR_HDR C
WHERE 1=1
AND CONTRAT=C.CONTRACT_NUM
AND (L.PARENT_CONTR_ID <> ' '
OR L.CHILD_CONTR_ID IS NOT NULL)
It seems I can't do this: AND CONTRAT=C.CONTRACT_NUM
How can I compare the coalesce column with another column?
Please use below query, you cannot use alias to join a value, instead you have to use complete expression. And you no need to use 1=1 condition as well.
SELECT
C.BUSINESS_UNIT
,COALESCE(L.CHILD_CONTR_ID
,L.PARENT_CONTR_ID) AS CONTRAT
, C.BILL_TO_CUST_ID
FROM C_LIE_VW L
,CONTR_HDR C
WHERE COALESCE(L.CHILD_CONTR_ID,L.PARENT_CONTR_ID)=C.CONTRACT_NUM
AND (L.PARENT_CONTR_ID <> '' OR L.CHILD_CONTR_ID IS NOT NULL);
Below is the join query if required,
SELECT
C.BUSINESS_UNIT
,COALESCE(L.CHILD_CONTR_ID
,L.PARENT_CONTR_ID) AS CONTRAT
, C.BILL_TO_CUST_ID
FROM C_LIE_VW L inner join
CONTR_HDR C
on (COALESCE(L.CHILD_CONTR_ID,L.PARENT_CONTR_ID)=C.CONTRACT_NUM )
WHERE (L.PARENT_CONTR_ID <> ' '
OR L.CHILD_CONTR_ID IS NOT NULL);
Related
I am trying to make this request. I added the group by because I had duplicates. I am getting the error:
Invalid column name for the columns in the group by.
I have read a lot of posts regarding this type of error but I am still stuck. Also I would like to know if I should use sum(). Help please.
INSERT INTO tabA
([load_number]
,[load_date]
,[no_command]
,[no_document]
,[id_transc]
,[division_cd]
,[activity_cd]
,[project_cd])
select 1 [load_number]
,getdate() [load_date]
,'' [no_command]
,'' [no_document]
,coalesce(c.id_numb,-1) [id_transc]
,coalesce(b.elem_cd,-1) [division_cd]
,coalesce(d.budget_cd,-1) [activity_cd]
,'' [project_cd]
from tabB b
left join tabC c on c.credit = b.account
left join tabD d on d.activity = SUBSTRING([b.name],CHARINDEX('-',[b.name])+1,LEN([b.name])) and d.transc = '1010'
group by [load_number]
,[load_date]
,[no_command]
,[no_document]
,[id_transc]
,[division_cd]
,[activity_cd]
,[project_cd]
If you are concerned about duplicates, you can just use select distinct:
select distinct 1 [load_number],
getdate() [load_date],
'' [no_command],
'' [no_document],
coalesce(c.id_numb,-1) [id_transc],
coalesce(b.elem_cd,-1) [division_cd],
coalesce(d.budget_cd,-1) [activity_cd],
'' [project_cd]
from tabB b left join
tabC c
on c.credit = b.account left join
tabD d
on d.activity = SUBSTRING([b.name],CHARINDEX('-',[b.name])+1,LEN([b.name])) and d.transc = '1010';
You can't use column aliases defined in the select in the group by in SQL Server.
I want to replace In with Like to make the query work.
SELECT
1 AS coddit, COD_CAT AS cam_cod, DES_CAT AS cam_desc,
LIVELLO_CAT AS livello, COD_CAT_PADRE AS cat_padre,
COD_L1, COD_L2, COD_L3, COD_L4, COD_L5, COD_L6
FROM
dbo.CLASS_ART
WHERE
1=1
AND TIPO_CLASS = 16 --B2B
AND LIVELLO_CAT = '0'
AND COD_CAT IN (SELECT DISTINCT CAT_MERCE.COD_CAT
FROM ART_LIST_PREZZI
INNER JOIN ART_ANA ON ART_LIST_PREZZI.COD_ART = ART_ANA.COD_ART
INNER JOIN CAT_MERCE ON ART_ANA.COD_CAT = CAT_MERCE.COD_CAT
AND ART_LIST_PREZZI.COD_LIST = 'EXPORT_002')
The comparison I would like to do with LIKE otherwise the query doesn't work well
the subquery returns more than one value and it is correct but if I use Like instead of IN I have this error message:
Query return more than 1 values
Using LIKE against a subquery that returns multiple records won't work. A solution would be to turn the IN condition to an EXISTS condition, like:
and exists (
select 1
from ART_LIST_PREZZI
inner join ART_ANA
on ART_LIST_PREZZI.COD_ART = ART_ANA.COD_ART
inner join CAT_MERCE
on ART_ANA.COD_CAT = CAT_MERCE.COD_CAT
and ART_LIST_PREZZI.COD_LIST = 'EXPORT_002'
where COD_CAT like '%' + CAT_MERCE.COD_CAT + '%'
)
Like has to be compared to a single string, so you need to set all your ids on a single string. You can do that using the for xml clause.
(SELECT DISTINCT CAST(CAT_MERCE.COD_CAT AS VARCHAR(32))
FROM ART_LIST_PREZZI
INNER JOIN ART_ANA ON ART_LIST_PREZZI.COD_ART = ART_ANA.COD_ART
INNER JOIN CAT_MERCE ON ART_ANA.COD_CAT = CAT_MERCE.COD_CAT
AND ART_LIST_PREZZI.COD_LIST = 'EXPORT_002'
FOR XML PATH(''))
Now I would delimite your ids by commas, so you don't find false positives, and compare it using like.
AND
(SELECT DISTINCT ',' + CAST(CAT_MERCE.COD_CAT AS VARCHAR(32)) + ','
FROM ART_LIST_PREZZI
INNER JOIN ART_ANA ON ART_LIST_PREZZI.COD_ART = ART_ANA.COD_ART
INNER JOIN CAT_MERCE ON ART_ANA.COD_CAT = CAT_MERCE.COD_CAT
AND ART_LIST_PREZZI.COD_LIST = 'EXPORT_002'
FOR XML PATH('')) LIKE '%,' + COD_CAT + ',%'
This would work, and you would have changed your IN operator with a LIKE operator, but I don't see the point of it, its performance would be worse than your original query.
Use EXISTS:
EXISTS (SELECT 1
FROM ART_LIST_PREZZI LP JOIN
ART_ANA A
ON LP.COD_ART = A.COD_ART JOIN
CAT_MERCE M
ON A.COD_CAT = M.COD_CAT AND
LP.COD_LIST = 'EXPORT_002' AND
CLASS_ART.COD_CAT LIKE M.COD_CAT
)
I assume that the logic you actually want uses wildcards:
CLASS_ART.COD_CAT LIKE CONCAT('%', M.COD_CAT, '%')
If so, it suggests an issue with the data model. Why would two columns with the same name (COD_CAT) need to be joined using LIKE instead of =.
I have the following extraction query
select A.documentid.Docid, A.documentId.Appid, A.timestamp, A.EventStatus, D.Sequence, D.EventAppName, E.Value as Federation
from `dbo.events` A left join `dam.eventsroot` B on A.documentid.docid = B.docid left join `dbo.documentroot` C on B.rootdocid=C.rootdocid
inner join `dbo.reference_status` D
on A.DocumentID.AppID=D.EventAppID and A.EventStatus = D.EventStatus left join unnest(C.metadata) E on E.Key='Federation'
where A.timestamp > TIMESTAMP_TRUNC(CURRENT_TIMESTAMP(),DAY)
The result is that in column FEDERATION i get different values and values of '' (nothing) and i want to change them to Null.
How can i do this?
Thank you very much
I could use this in simple way like
select A.documentid.Docid, A.documentId.Appid, A.timestamp, A.EventStatus,
D.Sequence, D.EventAppName,
Case
When LTrim(RTrim(E.Value)) = '' Then Null
Else E.Value
End AS Federation
from dbo.events A
left join dam.eventsroot B on A.documentid.docid = B.docid
left join dbo.documentroot C on B.rootdocid=C.rootdocid
inner join dbo.reference_status D on A.DocumentID.AppID=D.EventAppID and
A.EventStatus = D.EventStatus
left join unnest(C.metadata) E on E.Key='Federation'
where A.timestamp > TIMESTAMP_TRUNC(CURRENT_TIMESTAMP(),DAY)
there are functions like NULLIF(column , '') and REPLACE(column,'',NULL) which you can them in such this cases. u can use LTRIM(RTRIM(column)) so any extra spaces will be removed.
so like:
NULLIF(LTRIM(RTRIM(federation)), '')
REPLACE(LTRIM(RTRIM(federation)),'',NULL)
and so many other ways...
You can use nullif() in any database:
select nullif(federation, '')
You might want to remove white space in general, and do:
select nullif(trim(federation), '')
Or, perhaps:
select (case when trim(federation) <> '' then federation end)
I've got the following query.
The only "left" table is the one with the alias "o".
I want to specify the following. How can I do? Should I use a WITH temp construct?
AND ( NVL (domb.DOMB_CONTO_CORRENTE, ' ') != o.campo43
OR NVL (abi.abi_descrizione, ' ') != o.campo41
OR NVL (cab.cab_descrizione, ' ') != o.campo42)
Here's the complete statement:
SELECT /*+ parallel(o 64) */
o.stato, COUNT (1)
FROM CONF_RAGGRUPPAMENTI_FORN rgf,
CRD_RID_REL_DOMICILIAZIONE crrd,
CRD_DOMICILIAZIONI domb,
uff_abi abi,
uff_abi_cab cab,
CONTO_CLIENTE_T809 o,
eni_flussi_hub c,
eni_monitor mon
WHERE 1 = 1
--RGF - OUT
AND rgf.RGF_CODICE_RAGGRUPPAMENTO(+) = o.campo1
--Join tra OUT e la ENI_FLUSSI_HUB
AND o.id_messaggio = c.flh_id_messaggio(+)
AND o.d_pubblicazione = c.flh_data_elaborazione(+)
--Join tra ENI_FLUSSI_HUB e ENI_MONITOR
AND c.FLH_ID_MESSAGGIO = MON.MON_ID_MESSAGGIO(+)
AND c.FLH_TIPO_PROCESSO_COD = MON.MON_COD_TP_PROCESSO(+)
AND c.flh_flag_ann(+) = 'N'
AND mon_flag_ann(+) = 'N'
--Join da RGF a DOMB
AND rgf.UITR_IDENT_TIPI_RAGGR_ID(+) = 'MP'
AND rgf.RGF_RAGGRUPPAMENTO_FORN_ID = crrd.RGF_RAGGRUPPAMENTO_FORN_ID(+)
AND crrd.DOMB_DOMICILIAZIONE_ID = domb.DOMB_DOMICILIAZIONE_ID(+)
AND CRRD.CRRD_RID_REL_DOM_ID = crrd.crrd_storico_id
AND CRRD.CRRD_FLAG_ANN (+) = 'N'
AND domb.domb_flag_ann (+) = 'N'
AND rgf.rgf_flag_ann(+) = 'N'
--Join tra domb e abi e cab
AND DOMB.ABI_ID = abi.ABI_ID(+)
AND DOMB.CAB_ID = cab.CAB_ID(+)
--Filtro sulle date
AND o.d_pubblicazione BETWEEN TO_DATE ('06-apr-2013')
AND TO_DATE ('14-apr-2013')
--Solo i flussi che producono variazioni
AND ( NVL (domb.DOMB_CONTO_CORRENTE, ' ') != o.campo43
OR NVL (abi.abi_descrizione, ' ') != o.campo41
OR NVL (cab.cab_descrizione, ' ') != o.campo42)
GROUP BY o.stato
If you can, I would recommend rewriting your query in modern ANSI syntax. This makes the query not only more readable, but it's easier to apply predicates on the optional table in a clear manner. I've rewritten 'old' Oracle queries and it's usually a quick cut and paste job to move the join conditions from the WHERE clause to the FROM ... JOIN ... ON ... clause.
Then, any predicates that apply to the optional table are listed under the OUTER JOIN condition, not under the WHERE. For example (in a very rough example):
SELECT
mt.col1,
mt.col2,
ot.col3
-- other columns ...
FROM main_table mt
LEFT OUTER JOIN optional_table ot ON mt.col1 = ot.col1
AND ot.col2 = 'N'
AND NVL (ot.some_column, 'x') != mt.col5
-- Now the where for the result set and main table
WHERE
AND mt.col4 BETWEEN TO_DATE ('06-apr-2013') AND TO_DATE ('14-apr-2013')
-- Other conditions on the total result set.
I've found this easiest way to apply conditions to the optional table without excluding rows from the final set.
You do not need to use the + on the NVLs because you establish the outer join already on the ID of domp, abi, and cab.
I agree with the others that using JOIN statement makes more readable SQL Selects.
Do you have any trouble with the query?
I have 2 script as following:
First one:
SELECT [Fm].[Id], [Sdp].[FirstName], [Sdp].[LastName], [Sdp].[SSN],
[Sdp].[StoreName], [Sdp].[PostalCode], [Fc].[Id], [Sdp].[Address]
FROM [SRM].[SiteMembers].[DProfile] AS [Sdp]
INNER JOIN [SRM].[SiteMembers].[Member] AS [Sm]
ON [Sdp].[Member_Id] = [Sm].[Id]
INNER JOIN [FRM].[Members].[Member] AS [Fm]
ON [Sm].[UserId] = [Fm].[UserId]
INNER JOIN [SRM].[General].[City] AS [Sc]
ON [Sdp].[City_Id]=[Sc].[Id]
INNER JOIN [FRM].[General].[City] AS [Fc]
ON [Fc].[Title]=[Sc].[Title]
COLLATE SQL_Latin1_General_CP1_CI_AS
WHERE ISNUMERIC([Sdp].[PostalCode])=1;
And Second one:
SELECT [Fm].[Id], [Sdp].[FirstName], [Sdp].[LastName], [Sdp].[SSN],
[Sdp].[StoreName], 0, [Fc].[Id], [Sdp].[Address]
FROM [SRM].[SiteMembers].[DProfile] AS [Sdp]
INNER JOIN [SRM].[SiteMembers].[Member] AS [Sm]
ON [Sdp].[Member_Id] = [Sm].[Id]
INNER JOIN [FRM].[Members].[Member] AS [Fm]
ON [Sm].[UserId] = [Fm].[UserId]
INNER JOIN [SRM].[General].[City] AS [Sc]
ON [Sdp].[City_Id]=[Sc].[Id]
INNER JOIN [FRM].[General].[City] AS [Fc]
ON [Fc].[Title]=[Sc].[Title]
COLLATE SQL_Latin1_General_CP1_CI_AS
WHERE ISNUMERIC([Sdp].[PostalCode])=0;
The difference between this 2 script is that the first one select columns with numeric postal code and second one select 0 for the non numeric postal code so how can I merge this 2 script together in one script, I am not talking about Union, I am interesting to use some condition in select query for non numeric postal code select 0. Does any one have any idea?
I would skip the where statement and create one column for the Numeric postal code and one for the other one. Like this:
SELECT
[Fm].[Id],
[Sdp].[FirstName],
[Sdp].[LastName],
[Sdp].[SSN],
[Sdp].[StoreName],
(
CASE WHEN ISNUMERIC([Sdp].[PostalCode])=1
THEN 0
ELSE NULL
END
) AS NumericPostalCode,
(
CASE WHEN ISNUMERIC([Sdp].[PostalCode])=0
THEN [Sdp].[PostalCode]
ELSE NULL
END
) AS PostalCode,
[Fc].[Id],
[Sdp].[Address]
FROM
[SRM].[SiteMembers].[DProfile] AS [Sdp]
INNER JOIN [SRM].[SiteMembers].[Member] AS [Sm]
ON [Sdp].[Member_Id] = [Sm].[Id]
INNER JOIN [FRM].[Members].[Member] AS [Fm]
ON [Sm].[UserId] = [Fm].[UserId]
INNER JOIN [SRM].[General].[City] AS [Sc]
ON [Sdp].[City_Id]=[Sc].[Id]
INNER JOIN [FRM].[General].[City] AS [Fc]
ON [Fc].[Title]=[Sc].[Title]
COLLATE SQL_Latin1_General_CP1_CI_ASĀ“
Edit 1
I know that this will result in two columns. But you can not have to data types in one column. But I think that you can do it something like this as well.
SELECT
[Fm].[Id],
[Sdp].[FirstName],
[Sdp].[LastName],
[Sdp].[SSN],
[Sdp].[StoreName],
(
CASE WHEN ISNUMERIC([Sdp].[PostalCode])=0
THEN [Sdp].[PostalCode]
ELSE '0'
END
) AS PostalCode,
[Fc].[Id],
[Sdp].[Address]
This will work becuase the numeric one are '0' as a varchar.
Edit 2
You can also do it like this:
SELECT CAST('asdasd' AS sql_variant)
UNION ALL
SELECT CAST(0 AS sql_variant)
But this is a dirty solution for this problem. The sql_variant is a database object. So my conclusion is: Use to column if you what to have different data types. If the values can be the same data type use the same column. Do not use sql_variant to solve problems like this. You will pay a high price in maintaining the code.
Hope this help.
Use a case statement in the selected column list and remove the where clause:
SELECT [Fm].[Id], [Sdp].[FirstName], [Sdp].[LastName], [Sdp].[SSN],
[Sdp].[StoreName],
case when isnumeric([Sdp].[PostalCode]) = 1 then [Sdp].[PostalCode] else 0 end,
[Fc].[Id], [Sdp].[Address]
FROM [SRM].[SiteMembers].[DProfile] AS [Sdp]
INNER JOIN [SRM].[SiteMembers].[Member] AS [Sm]
ON [Sdp].[Member_Id] = [Sm].[Id]
INNER JOIN [FRM].[Members].[Member] AS [Fm]
ON [Sm].[UserId] = [Fm].[UserId]
INNER JOIN [SRM].[General].[City] AS [Sc]
ON [Sdp].[City_Id]=[Sc].[Id]
INNER JOIN [FRM].[General].[City] AS [Fc]
ON [Fc].[Title]=[Sc].[Title]
COLLATE SQL_Latin1_General_CP1_CI_AS