Error in writing SQL dynamic query - sql

My code is like this
DECLARE #QueryText as NVARCHAR(MAX);
SET #QueryText= 'select '"' + m.MACHINE_STREET + '"' AS MACHINE_LOCATION,
A.Country_Code AS Country,
(SELECT mibcp.REMARKS FROM tblMachineContact mibcp
where mibcp.mc_machine_pkey=m.pkey and mibcp.CONTACT_CATEGORY_PKEY=''IR'') AS REMARKS
from tblMachine m inner join tblAddress A
on m.Address_Pkey=A.Pkey
where m.Site= ''TSN'''
EXEC sp_Machine_Location,NULL,NULL,NULL,#QueryText
When running this dynamic query i am getting error at sub query.
(SELECT mibcp.REMARKS
FROM tblMachineContact mibcp
WHERE mibcp.mc_machine_pkey=m.pkey
AND mibcp.CONTACT_CATEGORY_PKEY=''IR'') AS REMARKS.
How to avoid this ?

That's probably cause your below quoted subquery part will return more than 1 record and you actually meant to fetch 1 record per row.
(SELECT mibcp.REMARKS FROM tblMachineContact mibcp
where mibcp.mc_machine_pkey=m.pkey and mibcp.CONTACT_CATEGORY_PKEY=''IR'') AS REMARKS
You can probably make your query like
select m.MACHINE_STREET AS MACHINE_LOCATION,
A.Country_Code AS Country,
mibcp.REMARKS
FROM tblMachineContact mibcp
join tblMachine m on mibcp.mc_machine_pkey = m.pkey
inner join tblAddress A on m.Address_Pkey = A.Pkey
where m.Site = 'TSN'
and mibcp.CONTACT_CATEGORY_PKEY = 'IR'

Related

how to use LIKE instead of IN with multiple values?

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 am converting Oracle queries to Standard Bigquery, i am gettting error "IN subquery is not supported inside join predicate."

I have converted oracle query into below standard bq but in last statement(IN subquery). I am getting error:
"IN subquery is not supported inside join predicate."
Please advise how to use IN subquery in bq in the below code
#Last part of the code
INNER JOIN (
SELECT
DISTINCT `domain-rr.oracle_DB_DB.he_project_assoc`.PARENT_ISBN
PARENT_ISBN,
SUM (`domain-rr.DB_RPT.PROJECT_GR_QTY`.GR_QTY) GR_QTY
FROM
`domain-rr.oracle_DB_DB.he_project_assoc`
INNER JOIN
`domain-rr.DB_RPT.PROJECT_GR_QTY`
ON
`domain-rr.oracle_DB_DB.he_project_assoc`.child_ISBN = `domain-
rr.DB_RPT.PROJECT_GR_QTY`.BIC_GCISBN
AND `domain-rr.oracle_DB_DB.he_project_assoc`.BREAK_LABEL <>
'Associated ISBNs'
GROUP BY
`domain-rr.oracle_DB_DB.he_project_assoc`.PARENT_ISBN) xx
ON
yy.PARENT_ISBN = xx.PARENT_ISBN
AND yy.CIRCULATION_INT < xx.GR_QTY
AND yy.PARENT_ISBN IN
( SELECT
DISTINCT _BIC_GCISBN
FROM
`domain-rr.DB_RPT.BIC_GM_AGCPOAODS00_BO_VW`
INNER JOIN
`domain-rr.oracle_DB_boadmin.fiscal_bo`
ON
_BIC_ZC2GRIRIN = 'G'
AND _BIC_ZCLOEKZ = ' '
AND SUBSTR (BOUND_DATE, 1, 6) = `domain-
rr.oracle_DB_boadmin.fiscal_bo`.PRIOR_FISC_YEAR_MONTH )
Can you try like this:
Select * from (
#Last part of the code
INNER JOIN (
SELECT
DISTINCT `pearson-rr.oracle_grdw_grdw.he_project_assoc`.PARENT_ISBN
PARENT_ISBN,
SUM (`pearson-rr.GRDW_RPT.PROJECT_GR_QTY`.GR_QTY) GR_QTY
FROM
`pearson-rr.oracle_grdw_grdw.he_project_assoc`
INNER JOIN
`pearson-rr.GRDW_RPT.PROJECT_GR_QTY`
ON
`pearson-rr.oracle_grdw_grdw.he_project_assoc`.child_ISBN = `pearson-
rr.GRDW_RPT.PROJECT_GR_QTY`.BIC_GCISBN
AND `pearson-rr.oracle_grdw_grdw.he_project_assoc`.BREAK_LABEL <>
'Associated ISBNs'
GROUP BY
`pearson-rr.oracle_grdw_grdw.he_project_assoc`.PARENT_ISBN) xx
ON
yy.PARENT_ISBN = xx.PARENT_ISBN
AND yy.CIRCULATION_INT < xx.GR_QTY
) AA
where AA.PARENT_ISBN IN
( SELECT
DISTINCT _BIC_GCISBN
FROM
`pearson-rr.GRDW_RPT.BIC_GM_AGCPOAODS00_BO_VW`
INNER JOIN
`pearson-rr.oracle_grdw_boadmin.fiscal_bo`
ON
_BIC_ZC2GRIRIN = 'G'
AND _BIC_ZCLOEKZ = ' '
AND SUBSTR (BOUND_DATE, 1, 6) = `pearson-
rr.oracle_grdw_boadmin.fiscal_bo`.PRIOR_FISC_YEAR_MONTH )

SQL Query - Dynamic Columns will not sort according to SO

I have created a pivot query that I want the cross applied dynamic 'columns' to sort in a specific way, and they will not.
This is how the dynamic 'columns' are being returned:
[Cd - Conc] [Cd - RL] [Cd - Q] [Cd - MDL]
This is how I want them to return:
[Cd - Conc] [Cd - Q] [Cd - MDL] [Cd - RL]
I have limited my query to one analyte "Cd" while I try to get the sort order as described above, but the total number of analytes is not known necessarily. I want them to order by analyte by conc, q, mdl, rl so this would look like [Cd - Conc] [Cd - Q] [Cd - MDL] [Cd - RL] [Se - Conc] [Se - Q] [Se - MDL] [Se - RL] [Zr - Conc] [Zr - Q] [Zr - MDL] [Zr - RL] etc
This is my code:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
--
-- This variable holds the field values that will pivot to become column headers.
--
DECLARE #cols nvarchar(max);
--
-- This variable holds the dynamic pivot query.
--
DECLARE #query nvarchar(max);
--
-- First, we need to get the dynamic 'columns'. We do this by replicating
-- the FROM and WHERE clause that will show up in the pivot query. In the
-- SELECT, we only need to create the dynamic 'columns'. We must replicate
-- the FROM and WHERE clause or we'll end up with all rows from AN.[abbreviation].
--
-- This query is inside the STUFF function, which can build a string without
-- resorting to looping constructs.
--
-- The QUOTENAME function wraps a string in brackets, e.g. my_col becomes [my_col].
--
-- The end result of this is we get a comma-separated string of the form:
-- [Ag],[As], ...
--
SELECT #cols = STUFF
(
(
SELECT DISTINCT
',' + QUOTENAME(AN.[abbreviation] + col)
FROM
[project] P
INNER JOIN [monitoring_event_type] MET ON P.[id] = MET.[project_id]
INNER JOIN [monitoring_event] ME ON MET.[id] = ME.[event_type_id]
INNER JOIN [sample] S ON ME.[id] = S.[event_id]
INNER JOIN [location] L ON L.[id] = S.[location_id]
INNER JOIN [analysis] A ON A.[sample_id] = S.[id]
INNER JOIN [result] R ON R.[analysis_id] = A.[id]
INNER JOIN [result_qualifier] RQ ON RQ.[id] = R.[id]
LEFT JOIN [result_validation] RV ON RV.[id] = R.[id]
LEFT JOIN [sample_type] ST ON ST.[id] = R.[sample_type_id]
INNER JOIN [analyte] AN ON AN.[id] = R.[analyte_id]
LEFT JOIN [parameter_type] PT ON PT.[id] = AN.[parameter_type_id]
LEFT JOIN [unit] U ON U.[id] = R.[unit_id]
LEFT JOIN [analyte_fraction] ANF ON ANF.[id] = R.[analyte_fraction_id]
LEFT JOIN [organization] O1 ON O1.[id] = S.[sampler_id]
LEFT JOIN [organization] O2 ON O2.[id] = A.[lab_id]
LEFT JOIN [analysis_method] AM ON AM.[id] = A.[analysis_method_id]
CROSS APPLY
(
SELECT ' - Conc',1 UNION ALL
SELECT ' - Q',2 UNION ALL
SELECT ' - MDL' ,3 UNION ALL
SELECT ' - RL', 4 --Do not use UNION ALL on the last line
) AS c (col,so)
WHERE
P.id = 6
AND S.sample_source = 'Field'
AND AN.abbreviation in('Cd')
-- AND AN.abbreviation in('Ba', 'Cd','Se','Zr')
--Adding FOR XML PATH to the end of a query allows you to output the results of the query as XML elements, with the element name contained in the PATH argument.
FOR XML PATH,TYPE
).value('.[1]','nvarchar(max)'), 1, 1, ''
); -- END of STUFF function
--
-- Now we build the dynamic query using #cols variable where needed.
--
SET #query = '
SELECT
pvt.[EventName]
,pvt.[Location]
,pvt.[FieldSampleID]
,pvt.[DateCollected]
,'+ #cols +'
FROM
(
SELECT
ME.event_name AS [EventName]
,O2.organization_name AS [LAB]
,A.sdg AS [SDG]
,L.name_or_geocode AS [Location]
,ST.type AS [SampleType]
,A.lab_sample_ident AS [LabSampleID]
,S.sample_ident AS [FieldSampleID]
,CAST(S.monitoring_date as Date) AS [DateCollected]
--
-- The following two fields represent the pivot parameters
--
,col = AN.[abbreviation] + col
,val
FROM [project] P
INNER JOIN [monitoring_event_type] MET ON P.[id] = MET.[project_id]
INNER JOIN [monitoring_event] ME ON MET.[id] = ME.[event_type_id]
INNER JOIN [sample] S ON ME.[id] = S.[event_id]
INNER JOIN [location] L ON L.[id] = S.[location_id]
INNER JOIN [analysis] A ON A.[sample_id] = S.[id]
INNER JOIN [result] R ON R.[analysis_id] = A.[id]
INNER JOIN [result_qualifier] RQ ON RQ.[id] = R.[id]
LEFT JOIN [result_validation] RV ON RV.[id] = R.[id]
LEFT JOIN [sample_type] ST ON ST.[id] = R.[sample_type_id]
INNER JOIN [analyte] AN ON AN.[id] = R.[analyte_id]
LEFT JOIN [parameter_type] PT ON PT.[id] = AN.[parameter_type_id]
LEFT JOIN [unit] U ON U.[id] = R.[unit_id]
LEFT JOIN [analyte_fraction] ANF ON ANF.[id] = R.[analyte_fraction_id]
LEFT JOIN [organization] O1 ON O1.[id] = S.[sampler_id]
LEFT JOIN [organization] O2 ON O2.[id] = A.[lab_id]
LEFT JOIN [analysis_method] AM ON AM.[id] = A.[analysis_method_id]
CROSS APPLY
(
SELECT '' - Conc'',CAST(R.[VALUE] AS varchar(20)) UNION ALL
SELECT '' - Q'',CAST(RQ.[qualifiers] AS varchar(20)) UNION ALL
SELECT '' - MDL'',CAST(RQ.[MDL] AS varchar(20)) UNION ALL
SELECT '' - RL'',CAST(RQ.[RL] AS varchar(20)) --Do not use UNION ALL on the last line
) AS c (col,val)
WHERE
P.id = 6
AND S.sample_source = ''Field''
AND AN.abbreviation in(''Cd'')
--AND AN.abbreviation in(''Ba'', ''Cd'',''Se'',''Zr'')
) AS t
PIVOT
(
Max(t.[val])
FOR col IN ('+ #cols +')
)AS pvt
ORDER BY pvt.[EventName], pvt.[Location];
';
--
-- Execute the sql string contained in #query.
--
--Print #query
EXECUTE(#query);
--Select (#query);
Use the SO column in an ORDER BY in the query that creates #cols.

Complex Query Incorrect Syntax Error

I have tried to search for a solution to this but I have not been able to find one that fits this situation.
First I must say that my SQL is a lot rusty. The following query is the most complex one I have ever done to date.
Here is the query:
Declare #root varchar(Max)
set #root = ''
Select
ib.irrnum, ib.status, pu.probtype,
ib.submitby, ta.[Task Action], ib.area, co.cost,
rc.rootcause, ib.jobnum
From
tbl_irrbase ib
Left Join
tbl_cost co On ib.irrnum = co.irrnum
Left join
(Select Distinct probtype, irrnum
From tbl_probtype) pu On ib.irrnum = pu.irrnum
Left Join
(Select Distinct rootcause, irrnum
From tbl_rtcause) rc On ib.irrnum = rc.irrnum
Left Join
(Select TOP 1
(owner + Space(1) + Convert(varchar(10), senddate, 101) + Space(1) + taskitem) As 'Task Action',
irrnum
From
(select * From tbl_taskaction) ta
Order by
senddate Desc, sendtime Desc) ta On ib.irrnum = ta.irrnum
left Join
(Select [#root] = #root + rs.rootsource + Space(3), irrnum
From tbl_rtsource rs
Where rs.entrydate Between '10/04/2016' And '10/06/2016'
Select #root As 'Root Source') sr On ib.irrnum = sr.irrnum
Where
ib.submitedate between '09/28/2016' And '10/05/2016'
My problem is with the last Left Join line. If I take the entire Select statement out and run it in SSMS it runs fine, no errors. But when I try and run it in this query I get an error, red squiggly line under 'Select #root As' telling me the following:
Incorrect Syntax near 'Select'.
Expecting ')', EXCEPT, or UNION
I do not know how to fix this. If I remove this last 'Left Join' line the query runs fine.
Any ideas?
Instead of the last LEFT JOIN, try something like this:
CROSS APPLY (
SELECT (
SELECT rs.rootsource + Space(3)
From tbl_rtsource rs
Where rs.entrydate Between '10/04/2016' And '10/06/2016'
AND rs.irrnum=ib.irrnum
FOR XML PATH('')
) AS rootsource
) sr
Then include sr.rootsource in the columns of the first SELECT.

T-SQL Nested Subquery

Not being a SQL expert, and also only being semi-competent in CTE, how can I code this statement use the resultset from the following subquery within the main query, as our SQL Server is 2000.
declare #subcategoryConcatenate varchar(3999)
set #subcategoryConcatenate = ''
select #subcategoryConcatenate = #subcategoryConcatenate + pumpCategoryName + ',' FROM
(SELECT
SCD.PUMPCATEGORYNAME,
SCD.ENGINECATEGORYNAME,
SCD.DETAILEDDESCRIPTION
FROM PRTTICKHDR PHDR
INNER JOIN BIDHDR BHDR ON PHDR.DELIV_TICKET_NUMBER = BHDR.DTICKET
INNER JOIN PRTTICKITEM PITM ON PHDR.CONNECTION_ID = PITM.CONNECTION_ID AND PHDR.DELIV_TICKET_NUMBER = PITM.DELIV_TICKET_NUMBER
LEFT JOIN SUBCATEGORYDESCRIPTION SCD ON PITM.ITEM = SCD.PUMPCATEGORY
WHERE SCD.pumpCategoryName IS NOT NULL)
subcategoryDescription
select #subcategoryConcatenate
SELECT
PHDR.CONNECTION_ID AS CONNECTION_ID,
BHDR.OFFICE AS OFFICE,
CMP.NAME AS DEPOT,
CMP.ADDR1 AS DEPOT_ADDR1,
CMP.ADDR2 AS DEPOT_ADDR2,
CMP.CITY AS DEPOT_CITY,
CMP.STATE AS DEPOT_STATE,
CMP.ZIP AS DEPOT_ZIP,
CMP.PHONENUM AS DEPOT_PHONE,
CMP.FAXNUM AS DEPOT_FAX,
ACT.NAME AS ACTIVITY,
SAL.SALES_PERSON_NAME AS SALESPERSON,
BHDR.DTICKET AS DELIV_TICKET_NUMBER,
BHDR.PO_NUMBER,
BHDR.CREATED AS CREATED_DATE,
BHDR.DDATE AS ESTIMATED_START_DATE,
BHDR.PROJ_STOP_DATE AS PROJECTED_STOP_DATE,
CUR.ID,
CUR.CODE,
CUR.EXCHANGE_RATE,
CST.TERMS,
BHDR.ORDBY AS ORDERED_BY,
PHDR.ORDERED_BY_CONTACT,
BHDR.ACCT AS ACCOUNT,
BHDR.NAME AS CUSTOMER,
BHDR.ADDR1 AS CUST_ADDR1,
BHDR.ADDR2 AS CUST_ADDR2,
BHDR.CITY AS CUST_CITY,
BHDR.STATE AS CUST_STATE,
BHDR.ZIP AS CUST_ZIP,
PHDR.SHIP_TO_NAME,
PHDR.SHIP_TO_ADDR1,
PHDR.SHIP_TO_ADDR2,
PHDR.SHIP_TO_CITY,
PHDR.SHIP_TO_STATE,
PHDR.SHIP_TO_ZIP,
PITM.PRINT_SEQUENCE,
PITM.ITEM,
PITM.SUBGROUP,
PITM.DESCRIPTION,
SCD.PUMPCATEGORYNAME,
SCD.ENGINECATEGORYNAME,
SCD.DETAILEDDESCRIPTION,
PITM.QUANTITY,
PITM.UNIT_OF_MEASURE,
PITM.BILLING_LOGIC_TYPE,
PITM.INVENTORY_TYPE,
PITM.CHARGEABLE_DAYS,
PITM.MINIMUM_CHARGE,
PITM.WEEKLY_CHARGE,
PITM.MONTHLY_CHARGE,
PITM.UNINVOICED_NET,
PITM.UNINVOICED_VAT
FROM PRTTICKHDR PHDR
INNER JOIN BIDHDR BHDR ON PHDR.DELIV_TICKET_NUMBER = BHDR.DTICKET
INNER JOIN PRTTICKITEM PITM ON PHDR.CONNECTION_ID = PITM.CONNECTION_ID AND PHDR.DELIV_TICKET_NUMBER = PITM.DELIV_TICKET_NUMBER
INNER JOIN COMPANY CMP ON BHDR.OFFICE = CMP.OFFICE
LEFT JOIN SUBCATEGORYDESCRIPTION SCD ON PITM.ITEM = SCD.PUMPCATEGORY
INNER JOIN ACTIVITIES ACT ON BHDR.ACTIVITY_ID = ACT.ID
INNER JOIN SALES_PERSON SAL ON BHDR.SALES_PERSON = SAL.SALES_PERSON
INNER JOIN CUSTOMERS CST ON BHDR.ACCT = CST.CUSTNUM
INNER JOIN CURRENCY CUR ON CST.CURRENCY_ID = CUR.ID
ORDER BY
BHDR.DTICKET,
PITM.PRINT_SEQUENCE
ASC
SQL Server 2000 doesn't support CTEs. Your options are to either make a view out of the subquery if it's used a lot, or to do an inline view:
select
.. stuff..
from
table1 t1
join table2 t2 on ...stuff...
join (
select
...
from
...
where
...
) inline on ... stuff ...
where
....
You need a user-defined function.
From the looks of it, each PRTTICKITEM can have more than one PUMPCATEGORY?
(The question needs to better explain the desired results.)
In that case, your UDF would look something like this:
CREATE FUNCTION GetPumpCategoriesByItem (#ItemID int)
RETURNS varchar (8000)
AS
BEGIN
DECLARE
#CategoryList varchar (8000)
SET #CategoryList = NULL -- MUST be null to avoid leading comma.
SELECT
#CategoryList = COALESCE (#CategoryList + ', ', '') + SCD.PUMPCATEGORYNAME
FROM
SUBCATEGORYDESCRIPTION SCD
WHERE
SCD.PUMPCATEGORY = #ItemID
ORDER BY
SCD.PUMPCATEGORYNAME
RETURN #CategoryList
END
.
To use it would be something like this:
SELECT
PITM.ITEM,
dbo.GetPumpCategoriesByItem (PITM.ITEM),
... ...
FROM
... ...
INNER JOIN PRTTICKITEM PITM ON ... ...
... ...