SSRS/Oracle - Calculated Field error message: ORA-01747 invalid table.column, table.column, or column specificatio/ - sql

The SQL query below worked... But when I add the "FreightCostsPerOrderSplit" fields (3 new fields), I get the ORA-01747 error message seen below. The conventions are similar to what was being done before in the SQL code, and I was unsure what could be causing this error message.
Error at line 49 ORA-01747: invalid user.table.column, table.column,
or column specification
As I was posting this question, I figured out the solution. I decided to post this answer for others who may come across this same problem.
The solution involved replacing COUNT(OHH.*) with COUNT(OHH.FieldName) in the divisor of the calculated fields. See the answer section for commentary regarding count(*) vs count(column-name) syntax.
, (SUM(cteLoadFreightAgg.TOTALFREIGHT)/ COUNT(OHH.*)) AS "TotalFreight_SplitPerOrder"
SQL code (broken at Line 49 with solution posted in answer):
/* A list of aggregated freight carrier data grouped by LOAD (no BILLTOCUST)
Pulled from [LOAD_CARRIER] table. Another option is [FRT_LOAD] which include LUMPER
SOURCE: Loads Underutilize Report
*/
cteLoadFreightAgg AS
(
SELECT
LOAD_CARRIER.LOAD_SEQ_CODE AS LoadNumber
, SUM(LOAD_CARRIER.FLAT_FRT + LOAD_CARRIER.FUEL_FRT + LOAD_CARRIER.DROP_FRT + LOAD_CARRIER.MISC_FRT + LOAD_CARRIER.OUT_ROUTE_FRT + LOAD_CARRIER.LAYOVER_FRT) AS TotalFreight
, SUM(LOAD_CARRIER.DROP_FRT + LOAD_CARRIER.MISC_FRT + LOAD_CARRIER.OUT_ROUTE_FRT + LOAD_CARRIER.LAYOVER_FRT) AS AssessorialsFreight
, SUM(LOAD_CARRIER.FLAT_FRT) AS FlatRateFreight
, SUM(LOAD_CARRIER.FUEL_FRT) AS FuelFreight
FROM
LOAD_CARRIER
GROUP BY
LOAD_CARRIER.LOAD_SEQ_CODE
)
SELECT
OHH.BILL_COMP_CODE
, LOAD.DEPART_FROM_WHSE_CODE
, OHH.SHIP_FROM_WHSE
, OHH.ORDER_SEQ_CODE
, OHH.LOAD_SEQ_CODE
, OHH.SHIP_DATE
, CARRIER.NAME AS CarrierName
, OHH.DELIVERY_DATE
, CUST.CUST_CODE || '-' || CUST.CUST_SHIPTO_CODE AS ShiptoCustCode
, CUST.NAME AS ShiptoName
, OHH.BILL_PO_ID
, CUST.CITY
, CUST.STATE_CODE
, LOAD.TALLY_DATE_TIME
, OHH.APPT_DATE
, OHH.APPT_TIME
, OHH.EST_PALLETS
, OHH.EST_GROSS_WGT
, OHH.EST_NET_WGT
, LOAD.CLASS_CODE
, SUM(ODH.WEIGHT_SHIPPED) AS "SUM_ODH_WeightShipped"
-- FreightCostLoad
, cteLoadFreightAgg.TOTALFREIGHT
, cteLoadFreightAgg.FUELFREIGHT
, (cteLoadFreightAgg.TOTALFREIGHT - cteLoadFreightAgg.FUELFREIGHT) AS "OTHERFREIGHT"
-- FreightCostsPerOrderSplit
, (SUM(cteLoadFreightAgg.TOTALFREIGHT)/ COUNT(OHH.*)) AS "TotalFreight_SplitPerOrder"
, (SUM(cteLoadFreightAgg.FUELFREIGHT) / COUNT(OHH.*)) AS "FuelFreight_SplitPerOrder"
, ((SUM(cteLoadFreightAgg.TOTALFREIGHT) - SUM(cteLoadFreightAgg.FUELFREIGHT))/ COUNT(OHH.*)) AS "OtherFreight_SplitPerOrder"
FROM
ROCCO.CARRIER CARRIER
INNER JOIN ROCCO.LOAD_CARRIER LOAD_CARRIER
ON CARRIER.CARRIER_CODE = LOAD_CARRIER.CARRIER_CODE
INNER JOIN ROCCO.ORD_HDR_HST OHH
ON LOAD_CARRIER.LOAD_SEQ_CODE = OHH.LOAD_SEQ_CODE
INNER JOIN ROCCO.ORD_DTL_HST ODH
ON OHH.ORDER_SEQ_CODE = ODH.ORDER_SEQ_CODE
INNER JOIN ROCCO.LOAD LOAD
ON OHH.LOAD_SEQ_CODE = LOAD.LOAD_SEQ_CODE
INNER JOIN ROCCO.CUSTOMER_SHIPTO CUST
ON OHH.CUST_CODE = CUST.CUST_CODE
AND OHH.CUST_SHIPTO_CODE = CUST.CUST_SHIPTO_CODE
INNER JOIN cteLoadFreightAgg
ON LOAD.LOAD_SEQ_CODE = cteLoadFreightAgg.LOADNUMBER
WHERE
-- OHH.SHIP_DATE BETWEEN :paramStartDate AND :paramEndDate
-- AND OHH.STATUS_CODE<>'DL'
-- AND OHH.BILL_COMP_CODE IN (:paramCompany)
-- AND LOAD.DEPART_FROM_WHSE_CODE IN (:paramWarehouse)
-- AND OHH.MASTER_ORDER_NBR IS NULL
-- AND LOAD.CLASS_CODE IN (:paramClassCode)
-- AND CUST.CUST_CODE || '-' || CUST.CUST_SHIPTO_CODE IN (:paramShipto)
-- /*
OHH.SHIP_DATE BETWEEN TO_DATE('10/1/2018', 'MM/DD/YYYY') AND TO_DATE('10/31/2018', 'MM/DD/YYYY')
AND OHH.STATUS_CODE<>'DL'
AND OHH.BILL_COMP_CODE=100
AND OHH.MASTER_ORDER_NBR IS NULL
-- */
GROUP BY
OHH.BILL_COMP_CODE
, LOAD.DEPART_FROM_WHSE_CODE
, OHH.SHIP_FROM_WHSE
, OHH.ORDER_SEQ_CODE
, OHH.LOAD_SEQ_CODE
, OHH.SHIP_DATE
, CARRIER.NAME
, OHH.DELIVERY_DATE
, CUST.CUST_CODE || '-' || CUST.CUST_SHIPTO_CODE
, CUST.NAME
, OHH.BILL_PO_ID
, CUST.CITY
, CUST.STATE_CODE
, LOAD.TALLY_DATE_TIME
, OHH.APPT_DATE
, OHH.APPT_TIME
, OHH.EST_PALLETS
, OHH.EST_GROSS_WGT
, OHH.EST_NET_WGT
, LOAD.CLASS_CODE
, cteLoadFreightAgg.FUELFREIGHT
, cteLoadFreightAgg.TOTALFREIGHT
ORDER BY
OHH.SHIP_DATE
*
Error at line 49
ORA-01747: invalid user.table.column, table.column, or column specification

Initially I had the calculated field as:
, (SUM(cteLoadFreightAgg.TOTALFREIGHT)/ COUNT(OHH.*)) AS "TotalFreight_SplitPerOrder".
For all 3 calculate fields, I changed the divisor field to reference a specific field and the error message was resolved. Then once that syntaxed parsed successfully, the SSRS report gave a "#VALUE" error message, and I had to use CAST() function to get a proper evaluation instead of an error message in the SSRS report.
, CAST((cteLoadFreightAgg.TOTALFREIGHT/ COUNT(OHH.ORDER_SEQ_CODE) OVER(PARTITION BY OHH.LOAD_SEQ_CODE)) AS NUMERIC(9,2)) AS "TotalFreight_SplitPerOrder"
So after resolving the original error message, I then figured out I should be doing a WINDOWING function to divide the value as the report requirements dictated.
I did some reading online for an answer to "Why did COUNT(FieldName) evaluate while COUNT(*) gave the error message?". I came across a few blog articles but they were mostly regarding performance concerns, not row count division or this error message I received.
https://www.sqlskills.com/blogs/conor/countstar-vs-countcolumn-vs-countdistinct-vs-countcol-over/
https://www.mssqltips.com/sqlservertip/4460/sql-server-count-function-performance-comparison/
https://www.sqlhammer.com/transact-sql-count-vs-countcolumn-vs-count1/

Related

How can i fix this problem with OR/AND clause in SQL

I have a set of patents that I have titles and abstracts on and would like to search in such a way that their final search algorithm requires the keyword “software” to be present, and none of the keywords “chip”, “semiconductor”, “bus”, “circuit” or “circuit” to be present.
i did This:
SELECT distinct
tls201_appln.docdb_family_id
, tls201_appln.appln_id
, [appln_auth]
, [appln_nr]
, [appln_kind]
, [appln_filing_date]
, [receiving_office]
, [earliest_publn_date]
, [granted]
, [nb_citing_docdb_fam]
, [nb_applicants]
, [nb_inventors]
, tls202_appln_title.appln_title
FROM tls201_appln
INNER JOIN tls202_appln_title ON tls201_appln.appln_id = tls202_appln_title.appln_id
INNER JOIN tls203_appln_abstr ON tls201_appln.appln_id = tls203_appln_abstr.appln_id
WHERE (appln_title like '%software%'
or appln_abstract like '%software%')
AND appln_title not like '%chip%'
or '%semiconductor%'
or '%circuity%'
or '%circuitry%'
or '%bus'%'
or appln_abstract not like '%chip%'
or '%semiconductor%'
or '%circuity%'
or '%circuitry%'
or '%bus'%'
AND appln_filing_year between 2003 and 2008
but im getting this error An expression of non-boolean type specified in a context where a condition is expected, near 'or'. What should i do?
This is wrong:
and appln_title not like '%chip%' or '%semiconductor%' or '%circuity%'
This is right:
and appln_title not like '%chip%'
and appln_title not like '%semiconductor%'
and appln_title not like '%circuity%'
Sample data would be helpful so I could test my code.
To help whoever maintains this code in the future, you'd do well to qualify your column names. It's difficult to know what's going on when I can't tell which table each column comes from.
This is considerably more verbose, but possibly easier to understand and maintain. Will this work?
with main as (
SELECT distinct
tls201_appln.docdb_family_id
, tls201_appln.appln_id
, [appln_auth]
, [appln_nr]
, [appln_kind]
, [appln_filing_date]
, [receiving_office]
, [earliest_publn_date]
, [granted]
, [nb_citing_docdb_fam]
, [nb_applicants]
, [nb_inventors]
, tls202_appln_title.appln_title
, appln_abstract
FROM tls201_appln
INNER JOIN tls202_appln_title ON tls201_appln.appln_id = tls202_appln_title.appln_id
INNER JOIN tls203_appln_abstr ON tls201_appln.appln_id = tls203_appln_abstr.appln_id
WHERE appln_title + ' ' + appln_abstract like '%software%'
AND appln_filing_year between 2003 and 2008
)
select docdb_family_id
, appln_id
, [appln_auth]
, [appln_nr]
, [appln_kind]
, [appln_filing_date]
, [receiving_office]
, [earliest_publn_date]
, [granted]
, [nb_citing_docdb_fam]
, [nb_applicants]
, [nb_inventors]
, appln_title
from main
except
select docdb_family_id
, appln_id
, [appln_auth]
, [appln_nr]
, [appln_kind]
, [appln_filing_date]
, [receiving_office]
, [earliest_publn_date]
, [granted]
, [nb_citing_docdb_fam]
, [nb_applicants]
, [nb_inventors]
, appln_title
from main
where exists (
select 1
from (
select '%chip%' as cond
union select '%semiconductor%'
union select '%circuity%'
union select '%circuitry%'
union select '%bus%'
) c
where appln_title like c.cond
or appln_abstract like c.cond
)
based on https://stackoverflow.com/a/1127100/9937026

Can you explain the meaning of a minus in a SQL select statement?

I am working with SQL and I found this snippet, my question is: what does it mean those minus symbols (-) inside the select statement? I know is a kind of some trick, but I can't find information online about how it is used, please any insight would be welcome.
I am referring to:
SELECT - sum(st.sales) AS sales
- sum(st.orders) AS orders
- sum(st.aov) AS aov
It seems to be related to ledger tables, if you have any documentation, blog or pdf please give me the link to check it.
The full SQL looks like this:
INSERT INTO sales_test
WITH source_query AS --find the existing values in the ledger table and invert them
(
SELECT
st.og_date
, st.merchant
, st.store_name
, st.country
, st.kam
, st.class
, st.origin
, - sum(st.sales) AS sales
, - sum(st.orders) AS orders
, - sum(st.aov) AS aov
, et.source_file_name
, et.source_file_timestamp
FROM
sales_test st
INNER JOIN
ext_sales_test et
ON
city_hash(et.og_date, et.merchant, et.store_name, et.country, et.kam, et.class, et.origin) = city_hash(st.og_date, st.merchant, st.store_name, st.country, st.kam, st.class, st.origin)
AND st.og_date = et.og_date
AND st.merchant = et.merchant
GROUP BY
st.og_date
, st.merchant
, st.store_name
, st.country
, st.kam
, st.class
, st.origin
, et.source_file_name
, et.source_file_timestamp
)
, union_query AS --if we union the incoming data with the inverted existing data, we get the difference that needs to be ledgered
(
SELECT *
FROM
source_query
UNION ALL
SELECT *
FROM
ext_sales_text
)
It makes the numeric value negative(if numeric value is negative, - - is positive), in your case it first performs the sum and then it makes it negative or positive:
As an example:
USE tempdb;
GO
DECLARE #Num1 INT;
SET #Num1 = 5;
SELECT #Num1 AS VariableValue, -#Num1 AS NegativeValue;
GO
Result set:
VariableValue NegativeValue
------------- -------------
5 -5
(1 row(s) affected)
Further info here

How to debug the error of invalid identifier in the following PL/SQL block?

For the below PLSQL code , I am getting Error report -
ORA-00904: "SRC"."PART_ID_CONSOLIDATED": invalid identifier
ORA-06512: at line 37 , I tried debugging it by printing the values of I.item_no , I.PART_ID_CONSOLIDATED , getting values correctly printed but still its showing invalid identifier , unable to debug this , please guide .
DECLARE
BEGIN
FOR T IN
(
SELECT * FROM TDTEMP.ITEM_MTRL_SPLIT_TMP
where regexp_like(MATERIAL_NAME, '[[:digit:]],[[:digit:]] % +[[:alpha:]]*')
)
LOOP
FOR I IN
(
WITH parsed as(
SELECT /*+ parallel(t,8) materialize */
T.item_no,T.item_type,T.bu_code_sup,T.bu_type_sup,T.FROM_PACK_DATE,T.PART_ID,T.MATERIAL_NAME,T.PART_ID_CONSOLIDATED,T.reporting_name,
regexp_substr(REGEXP_REPLACE(replace(replace(T.MATERIAL_NAME,'% ','% '),', ',','), '(\d+),(\d+)', '\1.\2'),'[^,]+',1,ROWNUM)
AS split_value
FROM dual
CONNECT BY level <= regexp_count(REGEXP_REPLACE(replace(T.MATERIAL_NAME,'% /','%/'), '(\d+),(\d+)', '\1.\2'),'[^,]+')
)
,in_pairs as(
select /*+ parallel(k,8) materialize */
item_no,item_type,bu_code_sup,bu_type_sup,FROM_PACK_DATE,PART_ID,material_name,PART_ID_CONSOLIDATED,reporting_name
,regexp_substr(split_value, '[0-9]+[.]*[0-9]+') as percentage
,trim(substr(split_value, instr(split_value, '%') + 1)) as component
from parsed k where split_value LIKE '%\%%' ESCAPE '\'
)
select /*+ parallel(it,8) */
distinct item_no,item_type,bu_code_sup,bu_type_sup,FROM_PACK_DATE,PART_ID,material_name,percentage,component,PART_ID_CONSOLIDATED,reporting_name
from in_pairs it
)
LOOP
merge into TDTEMP.ITEM_MTRL_SPLIT_TMP targ
using (
SELECT I.item_no,I.item_type,I.bu_code_sup,I.bu_type_sup,I.FROM_PACK_DATE,I.PART_ID,I.material_name,I.percentage,I.component,I.PART_ID_CONSOLIDATED,
I.reporting_name FROM DUAL
)src
on ( targ.item_no = src.item_no
and targ.item_type = src.item_type
and targ.bu_code_sup = src.bu_code_sup
and targ.bu_type_sup = src.bu_type_sup
and targ.part_id = src.part_id
and targ.from_pack_date = src.from_pack_date
and targ.component = src.component
and targ.percentage = src.percentage
and targ.material_name = src.material_name
and targ.PART_ID_CONSOLIDATED = src.PART_ID_CONSOLIDATED
)
when not matched then
insert (item_no ,
item_type ,
bu_code_sup,
bu_type_sup ,
from_pack_date ,
part_id ,
part_id_consolidated,
material_name ,
percentage ,
component ,
reporting_name,
plastic,
ii_date )
values( src.item_no ,
src.item_type ,
src.bu_code_sup ,
src.bu_type_sup ,
src.from_pack_date,
src.part_id ,
src.part_id_consolidated ,
src.material_name ,
src.percentage ,
src.component ,
src.reporting_name,
'N',
sysdate
)
when matched then
update set targ.percentage = src.percentage ,
targ.component = src.component ;
END LOOP ;
END LOOP ;
END ;
The short answer is that because you are selecting from dual, which only has a single dummy column, you need to give aliases to all of the values you are selecting in your using clause:
using (
SELECT I.item_no AS item_no, I.item_type AS item_type, I.bu_code_sup AS bu_code_sup,
I.bu_type_sup AS bu_type_sub, I.FROM_PACK_DATE AS from_pack_date,
I.PART_ID AS part_id, I.material_name AS material_name, I.percentage AS percentage,
I.component AS component, I.PART_ID_CONSOLIDATED AS part_id_consolidated,
I.reporting_name AS reporting_name
FROM DUAL
) src
db<>fiddle with a very simplified example. To some extent that also addresses the "how to debug" part of your question - break your failing block of code down into smaller and simpler parts to make it easier to see what's happening. And if you still can't work it out, you're much closer to a minimum reproducible example you can post without so much noise for others to wade through.
The long answer is to avoid the loops and do a single merge, as MTO suggested in a comment.

Group by - Non-group-by expression in select clause

Sorry you will have to bear with me as i am relativly new to SQL. I am querying an ODBC in EXCEL. At the moment my dataset is massive so i am looking to narrow it down by grouping it by company name and date. not all my columns are calculated fields.I have put the Sum on the two i need adding up. When i try to return the data i get the error of Non-group-by expression in select clause
Please can someone help me out.
SELECT
SopOrder_0.SooOrderNumber
, Company_0.CoaCompanyName
, InvoiceCreditItem_0.InvoiceCreditItemID
, InvoiceCreditItem_0.IciInvoiceApproved
, InvoiceCreditItem_0.InvoiceCreditID
, InvoiceCreditItem_0.CompanySiteID
, InvoiceCreditItem_0.VatID
, InvoiceCreditItem_0.NominalID
, InvoiceCreditItem_0.IciCreatedDate
, Sum(InvoiceCreditItem_0.IciTotalNettValue)
, Sum(InvoiceCreditItem_0.IciVatValue)
FROM
SBS.PUB.Company Company_0
, SBS.PUB.Customer Customer_0
, SBS.PUB.InvoiceCreditItem InvoiceCreditItem_0
, SBS.PUB.SopOrder SopOrder_0
WHERE
SopOrder_0.SopOrderID = InvoiceCreditItem_0.SopOrderID
AND InvoiceCreditItem_0.CompanyID = Customer_0.CompanyID
AND InvoiceCreditItem_0.CompanyID = Company_0.CompanyID
AND (Company_0.CoaCompanyName<>'ATOS')
AND InvoiceCreditItem_0.IciCreatedDate >= ?
GROUP BY
Company_0.CoaCompanyName, InvoiceCreditItem_0.IciCreatedDate

Why I need Group by in this simple query?

UPDATE :
-----
the error might be in sum(si.amt_pd) from item table (as there is no relation) :
select SUM(si.amt_pd)amt_pd from [HMIS_REPORTING].HMIS_RPT_ME.dbo.item i
where
is there a work around?
----------
I am trying to run this query. The query just fetches the amount of a month based on some tables. It is just a part of a big query.
select s.sales_Contract_Nbr
, s.Sales_Id
, s.Sale_Dt
, YEAR(s.Sale_Dt) 'YEAR'
, MONTH(s.Sale_Dt) 'MONTH'
, s.Sales_Need_TYpe_Cd
, s.Sales_Status_Cd
, si.Posted
, s.location_Cd
, jan2011 = (
select SUM(si.amt_pd)amt_pd
from [HMIS_REPORTING].HMIS_RPT_ME.dbo.item i
where i.Item_Id = si.Product_Item_ID
and i.Item_Cd <> '*INT'
and convert(varchar(10),SI.Sales_Item_Dt,126) >= '2011-01-01'
and convert(varchar(10),SI.Sales_Item_Dt,126) >= '2011-01-31'
) INTO dbo.#a_acomparision
FROM [HMIS_REPORTING].HMIS_RPT_ME.dbo.Sales S
, [HMIS_REPORTING].HMIS_RPT_ME.dbo.Sales_Item SI
WHERE SI.Sales_Id = S.Sales_Id
and s.Sales_Contract_Nbr in (
select distinct (Sales_Contract_Nbr)
from mountainviewContracts
where Sales_Contract_Nbr <> '')
but I am getting the following error message.
Msg 8120, Level 16, State 1, Line 1
Column 'HMIS_REPORTING.HMIS_RPT_ME.dbo.Sales.Sales_Contract_Nbr' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I just can't understand why my query should have a group by for sales_contract_nbr and even if I put in the group by clause it tells me that inner query si.Product_item_id and SI.sales_item_dt should also be contained in group by clause.
Please help me out.
Thanks in advance
This is a very subtle problem. However, I think the subquery should be:
select SUM(i.amt_pd)amt_pd from [HMIS_REPORTING].HMIS_RPT_ME.dbo.item i
That is, the alias should be i not si.
What is happening is that the sum in the subquery is on a value in the outer query. So, the SQL compiler assumes an aggregation query. As soon as the first column is found that is not an aggregation, it complains with the message that you have.
By the way, you should use proper join syntax, so you from clause looks like:
FROM [HMIS_REPORTING].HMIS_RPT_ME.dbo.Sales S join
[HMIS_REPORTING].HMIS_RPT_ME.dbo.Sales_Item SI
on SI.Sales_Id = S.Sales_Id
As #Gordon Linoff says, this is almost certainly because the query optimizer is treating this like a SUM operation, normalizing away the subquery for "jan2001".
If the amt_pd column is present in the ITEM table, Gordon's solution is the right one.
If not, you have to add the group by statement, as below.
select s.sales_Contract_Nbr
, s.Sales_Id
, s.Sale_Dt
, YEAR(s.Sale_Dt) 'YEAR'
, MONTH(s.Sale_Dt) 'MONTH'
, s.Sales_Need_TYpe_Cd
, s.Sales_Status_Cd
, si.Posted
, s.location_Cd
, jan2011 = (
select SUM(si.amt_pd)amt_pd
from [HMIS_REPORTING].HMIS_RPT_ME.dbo.item i
where i.Item_Id = si.Product_Item_ID
and i.Item_Cd <> '*INT'
and convert(varchar(10),SI.Sales_Item_Dt,126) >= '2011-01-01'
and convert(varchar(10),SI.Sales_Item_Dt,126) >= '2011-01-31'
) INTO dbo.#a_acomparision
FROM [HMIS_REPORTING].HMIS_RPT_ME.dbo.Sales S
, [HMIS_REPORTING].HMIS_RPT_ME.dbo.Sales_Item SI
WHERE SI.Sales_Id = S.Sales_Id
and s.Sales_Contract_Nbr in (
select distinct (Sales_Contract_Nbr)
from mountainviewContracts
where Sales_Contract_Nbr <> '')
GROUP BY s.sales_Contract_Nbr
, s.Sales_Id
, s.Sale_Dt
, YEAR
, MONTH
, s.Sales_Need_TYpe_Cd
, s.Sales_Status_Cd
, si.Posted
, s.location_Cd