Query gives me a syntax error in From clause error - sql

This SQL query runs perfectly in an older MS Access file but after recreating it for a newer table it gives me a Syntax error in the from clause.
select * from ( with dso as (select month, product_line, third_cust_indic as sales_type,
sum(sales) + sum(beg_snb_ra) as beg_sales,
What could be the problem?

If this is SQL Server, then the with statement needs to precede the select:
with dso as (
select . . .
. . .
)
select . . .

with dso as (select year, month, product_line_id, third_party_cust_indic as sales_type,
sum(beg_snb_sales) + sum(beg_snb_ra) as beg_snb_sales,
sum(snb_sales) + sum(snb_ra) as snb_sales,
sum(beg_snb_cost) as beg_snb_cost,
sum(snb_cost) as snb_cost,
sum(spa) as spa_amount,
sum(invoiced_sales) + coalesce(sum(ic_extended_price),0) as invoiced_sales,
sum(gross_invoiced_sales) as gross_invoiced_sales,
sum(invoiced_cost)+ coalesce(sum(ic_extended_cost),0) as cost,
sum(beg_bl_future) + sum(beg_bl_dated) + sum(beg_bl_alloc) + sum(beg_bl_not_produced) as beginning_backlog,
sum(bl_future) + sum(bl_dated) + sum(bl_alloc) + sum(bl_not_produced) as current_backlog,
sum(bl_alloc) as bl_alloc,
sum(bl_dated) as bl_dated,
sum(bl_future) as bl_future,
sum(bl_not_produced) as bl_not_produced,
sum(promos) + sum(edi_disc_allowance) + sum(new_store_allowance) + sum(ord_level_disc_allowance) + sum (rdc_allowance) + sum(cert_rec_allowance)
+ sum(defective_allowance) + sum(freight_allowance) + sum(adv_coop_allowance) + sum(store_svc_allowance) + sum(promo_amt) + sum(below_min_order_fee) as order_level_discounts,
manufacturing_location, inv_legal_entity || ' ' || inv_legal_entity_desc as shipping_location
from prodsales.monthly_sales_orders
where year = 2018
and month = 10
and (CUST_LEGAL_ENTITY = '001' )
-- or ar_legal_entity = '001')
and PRODUCT_LINE_ID <> '000'
and BUSINESS_UNIT_ID Not in ('OI','IC','BI','RF')
group by year, month, product_line_id, third_party_cust_indic, manufacturing_location, inv_legal_entity || ' ' || inv_legal_entity_desc
)
, Pl as (select distinct product_line_id as pl from dso)
, YN as (select distinct sales_type as slstyp, year, month, day from dso)
, pl_indic as (select * from pl, yn)
select * from DSO
... though you don't seem to be using PL, YN or PL_INDIC.

Your query looks like:
select *
from (
with dso as (
select
...
from prodsales.monthly_sales_orders
where
...
)
and ...
group by ...
),
Pl as (select ... from dso),
YN as (select ... from dso),
pl_indic as (select ... from YN)
There are a lot of problems here:
as answer by Gordon Linoff, the with statement must precede the select
the conditions after the end of the declaration of dso statement make not sense, they basically cannot relate to anything
P1 and YN are outside of the with statement, whereas their syntax suggest that they should belong to it : Pl as (...))
That's far too many issues to make it possible to provide suggestions on how to rewrite the query. It also makes it extremely unlikely that this ever ran on any database. You would need to entirely revise the logic of this query.

Related

SQL - Join Queries

Here I have two tables as student_information and exmaination_marks.
examination_marks table have 3 columns for three subjects and include their marks.
I want to select the roll_number and name of the student from the student_information table where sum of the three subject's marks in examination_marks table is less than 100.
Both table has roll_number as primary key.
Here is the query I wrote.
select
si.roll_number,
si.name
from
student_information as si
left outer join examination_marks as em on
si.roll_number = em.roll_number
where
sum(em.subject_one + em.subject_two + em.subject_three) < 100;
But I got an error saying "ERROR 1111 (HY000) at line 1: Invalid use of group function"
Can any one help me with this?
sum(em.subject_one + em.subject_two + em.subject_three)< 100
this is the problem . Try these
Where (SELECT subject_one + subject_two + subject_three FROM examination_marks WHERE em.roll_number = si.roll_number) < 100
SUM is an "aggregate function" which can only be used inside a query which has a GROUP BY clause.
To get the sum of values within the same row you need to use the + operator. If the columns are NULL-able then you'll also need to use COALESCE (or ISNULL) to prevent NULL values invalidating your entire expression.
Like so:
SELECT
si.roll_number,
si.name,
COALESCE( em.subject_one, 0 ) + COALESCE( em.subject_two, 0 ) + COALESCE( em.subject_three, 0 ) AS sum_marks
FROM
student_information AS si
LEFT OUTER JOIN examination_marks AS em ON
si.roll_number = em.roll_number
WHERE
COALESCE( em.subject_one, 0 ) + COALESCE( em.subject_two, 0 ) + COALESCE( em.subject_three, 0 ) < 100;
(If you're wondering why the COALESCE( em.subje... expression is repeated in the SELECT and WHERE clauses, that's because SQL is horribly designed by (obscene profanities) is an unnecessarily verbose language).

How to avoid duplicates in the STRING_AGG function SQL Server

I was testing a query in SQL in which I need to concatenate values ​​in the form of a comma-separated list, and it works, I just have the problem of duplicate values.
This is the query:
SELECT t0.id_marcas AS CodMarca,
t0.nombremarcas AS NombreMarca,
t0.imagenmarcas,
(SELECT String_agg((t2.name), ', ')
FROM exlcartu_devcit.store_to_cuisine t1
INNER JOIN exlcartu_devcit.cuisine t2
ON t1.cuisine_id = t2.cuisine_id
WHERE store_id = (SELECT TOP 1 store_id
FROM exlcartu_devcit.store
WHERE id_marcas = t0.id_marcas
AND status = 1)) AS Descripcion,
t0.logo,
t0.imagen,
(SELECT TOP 1 preparing_time
FROM exlcartu_devcit.store
WHERE id_marcas = t0.id_marcas
AND status = 1) AS Tiempo,
t0.orden,
(SELECT TOP 1 Avg(minimum_amount)
FROM exlcartu_devcit.store_delivery_zone
WHERE id_marcas = t0.id_marcas) AS MontoMinimo
FROM exlcartu_devcit.[marcas] t0
I thought the solution could be just adding a DISTINCT to the query to avoid repeated values ​​in this way ...
(SELECT STRING_AGG(DISTINCT (t2.name), ', ') AS Descripcion
But apparently the STRING_AGG() function does not support it, any idea how to avoid repeated values?
Simplest way is just select from select, like this:
with dups as (select 1 as one union all select 1 as one)
select string_agg(one, ', ') from (select distinct one from dups) q;
vs original
with dups as (select 1 as one union all select 1 as one)
select string_agg(one, ', ') from dups;

SQL STATEMENT keyword

While going through the SQL CTEs I came across this: CODE Project CTE
The code is:
WITH ShowMessage(STATEMENT, LENGTH)
AS
(
SELECT STATEMENT = CAST('I Like ' AS VARCHAR(300)), LEN('I Like ')
UNION ALL
SELECT
CAST(STATEMENT + 'CodeProject! ' AS VARCHAR(300))
, LEN(STATEMENT) FROM ShowMessage
WHERE LENGTH < 300
)
SELECT STATEMENT, LENGTH FROM ShowMessage
or even a small modified one:
WITH ShowMessage(STATEMENT, LENGTH)
AS
(
SELECT STATEMENT = 1, LEN('I Like ')
UNION ALL
SELECT
STATEMENT + 1
, LEN(STATEMENT) FROM ShowMessage
WHERE STATEMENT < 50
)
SELECT STATEMENT, LENGTH FROM ShowMessage
The above code works perfect, when I try the code as:
with k (TT,LL)
as
(
select TT= 1, 1
union all
select TT+1,1
WHERE TT < 50
)
select TT,LL from k
My code does not work, error is that COLUMN TT does not exists. After a careful observation found that the STATEMENT is a keyword (UI showed in blue color); then I started searching online for the meaning of this keyword but could not find one (Google always throws only SELECT statement - not the STATEMENT)
Could you please explain what is this STATEMENT keyword and where/how to use it. Or please point me to the right source to learn it.
Try below query :
;WITH k (TT,LL)
as
(
SELECT 1, 1
UNION ALL
SELECT TT+1,1
FROM k --- you miss that table
WHERE TT < 50
)
SELECT TT,LL FROM k
You missed to add table i.e k.
with k (TT,LL)
as
(
select TT=1 , 1
union all
select TT+1,1 From K
WHERE TT < 50
)
select TT,LL from k

Order by Function Results in Union Statement

I have a query that has multiple union statements where the last union statements results are derived from a function. I want to know how to sort the resultset based on the vchLastName of the function results. Here is the basis of the stored procedure.
select ID, objtype, Descr=coalesce(v.acctName, x.Descr), x.ihhid
from (
-----select statements----
UNION ALL
SELECT
pn.iPartyID,
'CONTACT',
ISNULL(vchFirstName,'') + ' ' + ISNULL(vchLastName,'') + ' ' +
CASE WHEN vchGoesBy IS NOT NULL THEN '(' + vchGoesBy + ')' ELSE ISNULL(vchGoesBy,'') END,
pn.iHHID
FROM CRM.dbo.cfn_PartyNameSearch(1, 'test') pn
WHERE pn.cPartyType = 'C'
)
x left join tableName v on v.id = x.id
and x.ObjType='ACCOUNT'
I want to sort by the pn.vchLastName for CONTACT. the other results sorting isn't a big deal honestly, and I am not able to edit the function that gives the results.
This general idea will work. You can work out the details
select 2 sortfield1
, whatever aliasName
from etc
union all
select 1 sortfield1
, yourFunctionResult aliasName
from etc
order by sortfield1, aliasName
Ordering takes place towards the end of the query execution, at least after all the data has been selected. Therefore you will have to order the entire result set at the end of the query. IIRC there is not conditonal ordering in T-SQL.

Transpose query creates nodes (SQL Server 2008)

I finally found the query to execute to get all ids (comma separated) for one content in one row.
Following query did the trick:
You don't need to look at the query because it already does what it should do.
SELECT
taxonomy_item_id,
SUBSTRING(
(SELECT ', ' + CAST(taxonomy_id AS varchar) AS Expr1
FROM taxonomy_item_tbl AS t2
WHERE (t1.taxonomy_item_id = taxonomy_item_id) AND (taxonomy_language_id = 2067)
ORDER BY taxonomy_item_id, taxonomy_id FOR XML PATH('')
), 1, 1000) AS taxonomy_ids
FROM
taxonomy_item_tbl AS t1
WHERE
(taxonomy_language_id = 2067) AND (taxonomy_item_id = 180555)
GROUP BY
taxonomy_item_id
The only problem is the data result I get:
180555 | <Expr1>, 404</Expr1><Expr1>, 405</Expr1><Expr1>, 723</Expr1><Expr1>, 1086</Expr1><Expr1>, 1087</Expr1><Expr1>, 1118</Expr1><Expr1>, 1124</Expr1><Expr1>, 1126</Expr1>
I don't need the <Expr1> nodes. Is there a way to delete this? If I delete AS Expr1in the query then it is automatically added back
Thanks
If you don't want the <Expr1> - then just don't ask for it!
You have:
(SELECT ', ' + CAST(taxonomy_id AS varchar) AS Expr1
That AS Expr1 causes the <Expr1> to be added - so just don't have that expression there.
Try
SELECT
taxonomy_item_id,
SUBSTRING(
(SELECT ', ' + CAST(taxonomy_id AS VARCHAR)
FROM dbo.taxonomy_item_tbl AS t2
WHERE t1.taxonomy_item_id = taxonomy_item_id
AND taxonomy_language_id = 2067
ORDER BY taxonomy_item_id, taxonomy_id
FOR XML PATH('')
), 1, 1000) AS taxonomy_ids
FROM
dbo.taxonomy_item_tbl AS t1
WHERE
taxonomy_language_id = 2067
AND taxonomy_item_id = 180555
GROUP BY
taxonomy_item_id