Query works, but not in function - postgresql

I've been trying to get this to work in a function. It works from command line only:
SELECT d.cta_id, d.cta_name, d.cta_marketing_text, d.cta_text,
c.category_id, c.category_name,
d.cta_link, d.adid, d.product_type, d.global_cta, d.active_flag,
TO_CHAR(d.date_created,'MM/DD/YYYY') AS date_created,
TO_CHAR(d.date_modified,'MM/DD/YYYY') AS date_modified,
TO_CHAR(p.placement_date,'MM/DD/YYYY') AS placement_date
FROM cta_article_data d
JOIN (SELECT p.cta_id, p.placement_date
FROM cta_placement_dates p
WHERE p.placement_date = CURRENT_DATE) AS p
ON d.cta_id = p.cta_id
JOIN (SELECT c.category_id, c.category_name
FROM categories c) AS c
ON c.category_id = ANY(STRING_TO_ARRAY(d.category_id,',')::int[]);
SELECT retrieve_cta_data();
ON d.cta_id = p.cta_id'" returned 3 columns
CONTEXT: PL/pgSQL function retrieve_current_cta() line 10 at assignment
I'm really stuck here if anyone can spot anything.

Related

Using SUBSTRING in JOIN condition

SAP says that the function SUBSTRING is not known when activating this code:
SELECT a~client, a~loobj1, a~lotyp, a~proid, a~lockr, a~fdate, a~tdate, a~gpart, a~vkont, a~cond_loobj,
a~actkey, a~uname, a~adatum, a~azeit, a~protected, a~laufd, a~laufi
FROM dfkklocks AS a
INNER JOIN dfkkop AS b ON SUBSTRING( a~loobj1,1,12 ) = b~opbel
WHERE b~augst = 9 AND a~lotyp = '02'
INTO CORRESPONDING FIELDS OF TABLE #gt_dfkklocks.

Query returning different number of rows, results in crosstab error

I get this error with my query, but I can't figure out what is wrong with it:
Query-specified return tuple has 135 columns but crosstab returns 295.
And here's my query: (The part highlighted in bold returns same number of rows when run separately in pgAdmin.)
SELECT X.*, pi.productcode, pi.productitemdesc, pi.retailsalesprice, cat.productcategorydesc FROM (
SELECT * FROM crosstab (
'SELECT a.productitem AS productitemid, l.locationcode, (CASE WHEN SUM(a.netamount) IS NOT NULL THEN SUM(a.netamount) ELSE 0 END) || ''#'' || (CASE WHEN SUM(a.quantity) IS NOT NULL THEN SUM(a.quantity) ELSE 0 END) AS sales_qty FROM invoiceitem a INNER JOIN invoiceinfo b ON a.invoice = b.invoiceid INNER JOIN locationinfo l ON b.location = l.locationid WHERE b.status !=2 AND l.locationtype = 1 AND l.status = 1 AND TO_CHAR (b.invoicedate, ''YYYY-MM-DD'')>=''2018-03-01'' AND TO_CHAR (b.invoicedate, ''YYYY-MM-DD'')<=''2018-03-03'' GROUP BY a.productitem, l.locationcode ORDER BY a.productitem',
'SELECT l.locationcode FROM locationinfo l INNER JOIN invoiceinfo b ON b.location = l.locationid
WHERE b.status !=2 AND l.locationtype = 1 AND l.status = 1 AND TO_CHAR (b.invoicedate, ''YYYY-MM-DD'')>=''2018-03-01'' AND TO_CHAR (b.invoicedate, ''YYYY-MM-DD'')<=''2018-03-03'' GROUP BY l.locationcode order by l.locationcode')
AS (productitemid int, "0007" text,"BE101" text,"BE1013" text,"BE1014" text,"BE102" text,"BE103" text,"BE1034" text,"BE104" text,"BE1040" text,"BE1043" text,"BE1044" text,"BE1045" text,"BE1046" text,"BE105" text,"BE106" text,"BE107" text,"BE108" text,"BE109" text,"BE110" text,"BE111" text,"BE112" text,"BE123" text,"BE1265" text,"BE1266" text,"BE1271" text,"BE1272" text,"BE1273" text,"BE1274" text,"BE1279" text,"BE1280" text,"BE1281" text,"BE1282" text,"BE1351" text,"BE1400" text,"BE1401" text,"BE1404" text,"BE141" text,"BE142" text,"BE193" text,"BE194" text,"BE2125" text,"BE2126" text,"BE2127" text,"BE2128" text,"BE3001" text,"BE3002" text,"BE3005" text,"BE3006" text,"BE3009" text,"BE3010" text,"BE3031" text,"BE3032" text,"BE3121" text,"BE3122" text,"BE3123" text,"BE3124" text,"BE3127" text,"BE3128" text,"BE3131" text,"BE3132" text,"BE3203" text,"BE3204" text,"BE325" text,"BE3253" text,"BE3254" text,"BE326" text,"BE332" text,"BE3503" text,"BE3504" text,"BE355" text,"BE356" text,"BE365" text,"BE366" text,"BE381" text,"BE382" text,"BE383" text,"BE384" text,"BE400" text,"BE401" text,"BE402" text,"BE403" text,"BE405" text,"BE406" text,"BE408" text,"BE409" text,"BE411" text,"BE412" text,"BE4311" text,"BE4316" text,"BE4401" text,"BE4402" text,"BE4521" text,"BE4522" text,"BE4551" text,"BE4552" text,"BE470" text,"BE473" text,"BE475" text,"BE481" text,"BE482" text,"BE601" text,"BE604" text,"BE609" text,"BE610" text,"BE7040" text,"BE7043" text,"BE7045" text,"BE7046" text,"BE7048" text,"BE7049" text,"BE708" text,"BE7111" text,"BE7112" text,"BE7127" text,"BE7128" text,"BE7217" text,"BE7218" text,"BE7307" text,"BE7308" text,"BE7351" text,"BE7352" text,"BE801" text,"BE802" text,"BE803" text,"BE804" text,"BE831" text,"BE832" text,"BE860" text,"BE861" text,"BE862" text,"BE863" text,"BE865" text,"BE981" text,"BE982" text
)) X
LEFT JOIN productitem pi ON X.productitemid = pi.productitemid
LEFT JOIN productcategory cat ON pi.productcategory = cat.productcategoryid
The bold part of
productitemid int, "0007" text,"BE101" text,"BE1013" text,"BE1014" text,"BE102" text,"BE103" text,"BE1034" text,"BE104" text,"BE1040" text,"BE1043" text,"BE1044" text,"BE1045" text,"BE1046" text,"BE105" text,"BE106" text,"BE107" text,"BE108" text,"BE109" text,"BE110" text,"BE111" text,"BE112" text,"BE123" text,"BE1265" text,"BE1266" text,"BE1271" text,"BE1272" text,"BE1273" text,"BE1274" text,"BE1279" text,"BE1280" text,"BE1281" text,"BE1282" text,"BE1351" text,"BE1400" text,"BE1401" text,"BE1404" text,"BE141" text,"BE142" text,"BE193" text,"BE194" text,"BE2125" text,"BE2126" text,"BE2127" text,"BE2128" text,"BE3001" text,"BE3002" text,"BE3005" text,"BE3006" text,"BE3009" text,"BE3010" text,"BE3031" text,"BE3032" text,"BE3121" text,"BE3122" text,"BE3123" text,"BE3124" text,"BE3127" text,"BE3128" text,"BE3131" text,"BE3132" text,"BE3203" text,"BE3204" text,"BE325" text,"BE3253" text,"BE3254" text,"BE326" text,"BE332" text,"BE3503" text,"BE3504" text,"BE355" text,"BE356" text,"BE365" text,"BE366" text,"BE381" text,"BE382" text,"BE383" text,"BE384" text,"BE400" text,"BE401" text,"BE402" text,"BE403" text,"BE405" text,"BE406" text,"BE408" text,"BE409" text,"BE411" text,"BE412" text,"BE4311" text,"BE4316" text,"BE4401" text,"BE4402" text,"BE4521" text,"BE4522" text,"BE4551" text,"BE4552" text,"BE470" text,"BE473" text,"BE475" text,"BE481" text,"BE482" text,"BE601" text,"BE604" text,"BE609" text,"BE610" text,"BE7040" text,"BE7043" text,"BE7045" text,"BE7046" text,"BE7048" text,"BE7049" text,"BE708" text,"BE7111" text,"BE7112" text,"BE7127" text,"BE7128" text,"BE7217" text,"BE7218" text,"BE7307" text,"BE7308" text,"BE7351" text,"BE7352" text,"BE801" text,"BE802" text,"BE803" text,"BE804" text,"BE831" text,"BE832" text,"BE860" text,"BE861" text,"BE862" text,"BE863" text,"BE865" text,"BE981" text,"BE982" text
AND
SELECT l.locationcode FROM locationinfo l INNER JOIN invoiceinfo b ON b.location = l.locationid
WHERE b.status !=2 AND l.locationtype = 1 AND l.status = 1 AND TO_CHAR (b.invoicedate, ''YYYY-MM-DD'')>=''2018-03-01'' AND TO_CHAR (b.invoicedate, ''YYYY-MM-DD'')<=''2018-03-03'' GROUP BY l.locationcode order by l.locationcode
When run seperately, I get 295 results which is correct. However putting it together in the whole query gets the error.
The manual:
The remaining output columns must have the type of the last column of the source_sql query's result, and there must be exactly as many of them as there are rows in the category_sql query's result.
crosstab(text, text) with a dynamic (!) SELECT query as 2nd parameter is very error prone, since the output column list is static. You should also generate the output column list dynamically. Example:
Dynamic alternative to pivot with CASE and GROUP BY
That aside, the different number of rows returned from the same query, may very well be due to a different timezone setting in the two different sessions.
You have the expression TO_CHAR(b.invoicedate, 'YYYY-MM-DD') in your predicates. If b.invoicedate is type timestamptz the result depends on the timezone setting. Consider:
SET timezone = '+10';
SELECT TO_CHAR(timestamptz '2018-04-07 23:30+0', 'YYYY-MM-DD');
to_char
----------
2018-04-08
SET timezone = '-10';
SELECT TO_CHAR(timestamptz '2018-04-07 23:30+0', 'YYYY-MM-DD');
to_char
----------
2018-04-07
Solution
To remove the dependency on the timezone setting, use absolute values.
to_char() is expensive complication in this place to begin with. Drop that and adjust the predicate.
Provide timestamptz values to match your column. This also allows indexes to be used (if applicable).
Return Table Type from A function in PostgreSQL
Use time zone names (not offsets or abbreviations) to avoid more misunderstandings.
Ignoring timezones altogether in Rails and PostgreSQL
Use dollar-quoting to clean up the quote mess.
Insert text with single quotes in PostgreSQL
I suggest this as 2nd parameter:
$$
SELECT l.locationcode
FROM locationinfo l
JOIN invoiceinfo b ON b.location = l.locationid
WHERE b.status <> 2 AND l.locationtype = 1 AND l.status = 1
AND b.invoicedate >= timestamptz '2018-03-01 Europe/Vienna'
AND b.invoicedate < timestamptz '2018-03-04 Europe/Vienna'
GROUP BY 1
ORDER BY 1
$$
Replace Europe/Vienna in my example with the time zone name defining your dates.
Note 2018-03-04 to include all of 2018-03-03 like you intended.

LINQ from objects Left Join

I have a linq query that works fine when I join two tables, but when I include another table, it does not return data. Please help me figure out what I am doing wrong.
First Linq returns data:
var q = (from c in _context.Complaint
join cl in _context.Checklist on c.COMP_ID equals cl.COMP_ID into clleft
from cls in clleft.DefaultIfEmpty()
orderby c.timestamp descending
select new
{
FileNum = c.FileNum
}).AsQueryable().Distinct();
return q;
When I add this table, no data returns
var q = (from c in _context.Complaint
join cl in _context.Checklist on c.COMP_ID equals cl.COMP_ID into clleft
from cls in clleft.DefaultIfEmpty()
join oim in _context.OIM_EMPLOYEE on cls.MonitorEnteredEmpID equals oim.EmpID into oimleft
from oims in oimleft.DefaultIfEmpty()
orderby c.timestamp descending
select new
{FileNum = c.FileNum
}).AsQueryable().Distinct();
return q;

multiplication in group by , dyslexia

Now this is a simple insert query with one subquery and it's working perfectly:
INSERT INTO CSolutions..Report2
SELECT Nov.Chain, CG.Grouping, reg.code as regcode,reg.pname,reg.fname,reg.sname, SUM(NS.Currency) as sumeur , sum(ns2.kpl) as sumkpl,0,0,0,0
FROM CSolutions..NovSales NS,CSolutions..NSaleskpl NS2, CSolutions..NovCGroup CG, sales..reg_eng reg,
(SELECT DISTINCT P.Code, Nov.Chain
FROM Register..Pcy P
INNER JOIN Register..TCustomer TC ON (P.Code = TC.PCode)
INNER JOIN CSolutions..Novies2 Nov ON (TC.Code = Nov.TCode)
) AS Nov
WHERE NS.SpCode = CG.SpCode and ns.spcode = ns2.spcode AND Ns.PCode = Nov.Code
and ns.spcode = reg.code
and ns.pcode = ns2.pcode
**and NS.SalesMonth = '201205'
and NS2.SalesMonth = '201205'**
GROUP BY Nov.Chain, CG.Grouping , reg.code,reg.pname,reg.fname,reg.sname
This is derivate of the same query, but it's not working correctly:
INSERT INTO CSolutions..Report2
SELECT Nov.Chain, CG.Grouping, reg.code as regcode,reg.pname,reg.fname,reg.sname, SUM(NS.Currency) as sumeur , sum(ns2.kpl) as sumkpl,0,0,0,0
FROM CSolutions..NovSales NS,CSolutions..NSaleskpl NS2, CSolutions..NovCGroup CG, sales..reg_eng reg,
(SELECT DISTINCT P.Code, Nov.Chain
FROM Register..Pcy P
INNER JOIN Register..TCustomer TC ON (P.Code = TC.PCode)
INNER JOIN CSolutions..Novies2 Nov ON (TC.Code = Nov.TCode)
) AS Nov
WHERE NS.SpCode = CG.SpCode and ns.spcode = ns2.spcode AND Ns.PCode = Nov.Code
and ns.spcode = reg.code
and ns.pcode = ns2.pcode
**and NS.SalesMonth between '201201' and '201205'
and NS2.SalesMonth between '201201' and '201205'**
GROUP BY Nov.Chain, CG.Grouping , reg.code,reg.pname,reg.fname,reg.sname
This will give 5 times the 5 month sum amount,
I am a dyslexic and i have hard time to spot the error, I hope someone can help me ?? :)
There is no join on the salesmonth in CSolutions..NovSales and CSolutions..NSaleskpl NS2. In the frist query this does not matter because you are only looking at one salesmonth. In the second query I presume there are multiple salesmonth's as you are selecting a range of value from each table. You are getting a cross join because of this of salesmonth's because of this.

T-SQL Delete command basing on table variable

I need to delete some rows from table where indexes are equal indexes in table variable
declare #m_table as table
(
number NUMERIC(18,0)
)
...
inserting some rows into #m_table
...
DELETE ct FROM [dbo].[customer_task] ct
inner join project_customer pc on pc.id_customer = #m_table.number
inner join customer_user cu on cu.id_project_customer = pc.id
WHERE ct.id_csr_user = cu.id AND ct.id_status = 1;
but this code generates an error: Must declare the scalar variable "#m_table" How to solve that ?
You probably have a 'GO' (a batch separator) in those '...'
Variable declarations do not span batches.
The error means that SQL is expecting you to treat #m_table like a standard table, rather than a scalar (int, bit, etc.) variable. Perhaps something like this will work?
DELETE ct FROM [dbo].[customer_task] ct
WHERE ct.id_csr_user IN (
SELECT cu.id FROM customer_user cu
INNER JOIN project_customer pc ON pc.id = cu.id_project_customer
WHERE pc.id_customer IN (SELECT number FROM #m_table.number)
) AND ct.id_status = 1;