I am having some trouble writing a sql update function. I Have a table of quotes and a second table of products associated with those quotes. I am trying to set all the statuses of quotes with certain $ values based on the products. I cant seem to format this query correctly (code below). I know code is limited to 1 ID currently trying to test with 1 before I remove that portion.
sqlStringUpdate = "UPDATE fq SET fq.spQuoteStatus = 5 From factQuote fq (LEFT JOIN FactQuoteProduct as fqp on fq.spQuoteID=fqp.fk_spQuoteID) " & _
"WHERE fq.spQuoteID = 4844 and ((sum(fqp.ItemTotal) <2000 and fq.quoteDate < #" & firstset & "#) or ( fq.bu=3401 and sum(fqp.ItemTotal) <10000 and fq.quoteDate < #" & secondset & "# ) or ( fq.bu>3401 and sum(fqp.ItemTotal) <10000 and fq.quoteDate < #" & secondset & "#));"
error code: error 3075(syntax error (missing operator) in query expression '5 Left JOIN factQUotePRoduct as fqp on fq.spQUoteID=fqp.fk_spQuoteID')
first problem is the LEFT JOIN should not be in parenthesis.
second problem, you need to calculate the aggregate before the update, you can solve this using CTE syntax, try something like this:
;with
fqp as (
select fk_spQuoteID, sum(ItemTotal) sum_ItemTotal
from FactQuoteProduct
group by fk_spQuoteID
)
UPDATE fq SET fq.spQuoteStatus = 5
From factQuote fq
LEFT JOIN fqp on fq.spQuoteID=fqp.fk_spQuoteID
WHERE fq.spQuoteID = 4844
and (
(fqp.sum_ItemTotal <2000 and fq.quoteDate < #firstset)
or ( fq.bu=3401 and fqp.sum_ItemTotal <10000 and fq.quoteDate < #secondset )
or ( fq.bu>3401 and fqp.sum_ItemTotal <10000 and fq.quoteDate < #secondset )
);
if you are not common with CTE syntax you can use nested select like this:
UPDATE fq SET fq.spQuoteStatus = 5
From factQuote fq
LEFT JOIN (
select fk_spQuoteID, sum(ItemTotal) sum_ItemTotal
from FactQuoteProduct
group by fk_spQuoteID
) as fqp on fq.spQuoteID=fqp.fk_spQuoteID
WHERE fq.spQuoteID = 4844
and (
(fqp.sum_ItemTotal <2000 and fq.quoteDate < #firstset)
or ( fq.bu=3401 and fqp.sum_ItemTotal <10000 and fq.quoteDate < #secondset )
or ( fq.bu>3401 and fqp.sum_ItemTotal <10000 and fq.quoteDate < #secondset )
);
this should do the trick
Related
im doing a query on vba excel, i ave a problem with this query:
SQLStr = "SELECT DISTINCT (t2.COD_CF) AS CODICE_CLIENTE, (t2.RAG_SOC_CF) AS CLIENTE, (t1.DES_HEAD_DOC) AS COMMESSA_E_DESCRIZIONE, t1.DATA_PREV_FIN_LAV AS GREZZO_CONFERMATO, MIN(t4.DATA_INIZIO) AS PRIMO_CARICO, MAX(t4.DATA_FINE) AS ULTIMO_CARICO, " & _
"(TRUNC(MAX(t1.DATA_PREV_FIN_LAV)) - TRUNC(t4.DATA_INIZIO) ) - " & _
"((((TRUNC(MAX(t1.DATA_PREV_FIN_LAV),'D'))-(TRUNC(t4.DATA_INIZIO,'D')))/7)*2) - " & _
"(CASE WHEN TO_CHAR(t4.DATA_INIZIO,'DY','nls_date_language=english')='SUN' THEN 1 ELSE 0 END) - " & _
"(CASE WHEN TO_CHAR(MAX(t1.DATA_PREV_FIN_LAV),'DY','nls_date_language=english')='SAT' THEN 1 ELSE 0 END) as GG_DIFFERENZA " & _
"FROM COMM_LAV t1 " & _
"INNER JOIN CF t2 ON t1.COD_CF_INTE = t2.COD_CF " & _
"INNER JOIN COMM_LAV_LNK t3 ON t1.DOC_ID = t3.DOC_ID " & _
"INNER JOIN ORP_EFF_CICLI_ESEC t4 ON t3.LNK_DOC_ID = t4.DOC_ID " & _
"WHERE t1.DATA_PREV_FIN_LAV >= '" & startDate & "' AND t1.DATA_PREV_FIN_LAV <= '" & endDate & "' AND t4.COD_CICLO <> 'LEV01' " & _
"GROUP BY t2.COD_CF, t2.RAG_SOC_CF, t1.DES_HEAD_DOC, t1.DATA_PREV_FIN_LAV " & _
"ORDER BY t1.DES_HEAD_DOC, t1.DATA_PREV_FIN_LAV, MIN(t4.DATA_INIZIO) "
I get this error: ORA-00979: not a GROUP BY expression
this error there is only when i do the TRUNC() function, someone can help me and explain this group by
UPDATE
I tryed to use oracle and i hav e edit the query like this:
SELECT (t2.COD_CF) AS CODICE_CLIENTE, (t2.RAG_SOC_CF) AS CLIENTE, (t1.DES_HEAD_DOC) AS COMMESSA_E_DESCRIZIONE, t1.DATA_PREV_FIN_LAV AS GREZZO_CONFERMATO, MIN(t4.DATA_INIZIO) AS PRIMO_CARICO, MAX(t4.DATA_FINE) AS ULTIMO_CARICO,
(TRUNC(MAX(t1.DATA_PREV_FIN_LAV)) - TRUNC(t4.DATA_INIZIO)) AS DIFF
FROM COMM_LAV t1
INNER JOIN CF t2 ON t1.COD_CF_INTE = t2.COD_CF
INNER JOIN COMM_LAV_LNK t3 ON t1.DOC_ID = t3.DOC_ID
INNER JOIN ORP_EFF_CICLI_ESEC t4 ON t3.LNK_DOC_ID = t4.DOC_ID
WHERE t1.DATA_PREV_FIN_LAV >= '01-OCT-20' AND t1.DATA_PREV_FIN_LAV <= '30-OCT-20' AND t4.COD_CICLO <> 'LEV01'
GROUP BY t2.COD_CF, t2.RAG_SOC_CF, t1.DES_HEAD_DOC, t1.DATA_PREV_FIN_LAV
ORDER BY t1.DES_HEAD_DOC, t1.DATA_PREV_FIN_LAV, MIN(t4.DATA_INIZIO)
but i have always this error: ORA-00979: not a GROUP BY expression
Why the trunc function give me this error?
The GROUP BY clause needs to include all the fields in your SELECT that are not being GROUPED. You have omitted this one:
(TRUNC(MAX(t1.DATA_PREV_FIN_LAV)) - TRUNC(t4.DATA_INIZIO)) AS DIFF
Even though you have an aggregation function in there (MAX), overall this is a TRUNC statement and so is not an aggregation.
I think logically the following 2 statements are the same (at least as long as B < A):
MAX(A) - B == MAX(A-B)
therefore you should be able to re-write your statement as the following and still get the same result:
MAX(TRUNC(t1.DATA_PREV_FIN_LAV) - TRUNC(t4.DATA_INIZIO)) AS DIFF
You are missing the column TRUNC(t4.DATA_INIZIO) in the GROUP BY:
SELECT t2.COD_CF AS CODICE_CLIENTE, t2.RAG_SOC_CF AS CLIENTE,
t1.DES_HEAD_DOC AS COMMESSA_E_DESCRIZIONE,
t1.DATA_PREV_FIN_LAV AS GREZZO_CONFERMATO,
MIN(t4.DATA_INIZIO) AS PRIMO_CARICO,
MAX(t4.DATA_FINE) AS ULTIMO_CARICO,
(TRUNC(MAX(t1.DATA_PREV_FIN_LAV)) -
TRUNC(t4.DATA_INIZIO)
--------^ Not in GROUP BY
) AS DIFF
FROM COMM_LAV t1 JOIN
CF t2
ON t1.COD_CF_INTE = t2.COD_CF JOIN
COMM_LAV_LNK t3
ON t1.DOC_ID = t3.DOC_ID JOIN
ORP_EFF_CICLI_ESEC t4
ON t3.LNK_DOC_ID = t4.DOC_ID JOIN
WHERE t1.DATA_PREV_FIN_LAV >= DATE '2020-10-01' AND
t1.DATA_PREV_FIN_LAV <= DATE '2020-10-30' AND
t4.COD_CICLO <> 'LEV01'
GROUP BY t2.COD_CF, t2.RAG_SOC_CF, t1.DES_HEAD_DOC, t1.DATA_PREV_FIN_LAV,
TRUNC(t4.DATA_INIZIO)
---------^ add to GROUP BY
ORDER BY t1.DES_HEAD_DOC, t1.DATA_PREV_FIN_LAV, MIN(t4.DATA_INIZIO);
Note that Oracle supports date literals using the DATE keyword. I strongly recommend that you use that.
Using VBA, I want join a selection of one table to another, based on some conditions. The solution is probably simple, but I just can't find the error. I get a Runtime Error -2147217900 (80040e14) "Syntax-Error in join operation".
SELECT *
FROM [target$] AS Ziel
LEFT JOIN
(
SELECT *
FROM [source$]
WHERE [Zust].[FS] = 3
AND Year([Zust].[DATUM_1A])=2018 as Zust)
ON (
[Ziel].[Lage] = [Zust].[LAGE]
AND ((
[Zust].[BKM] < [Zust].[VKM]
AND [Ziel].[MitteBetrKm] <= [Zust].[VKM]
AND [Ziel].[MitteBetrKm] > [Zust].[BKM])
OR (
[Zust].[BKM] > [Zust].[VKM]
AND [Ziel].[MitteBetrKm] >= [Zust].[VKM]
AND [Ziel].[MitteBetrKm] < [Zust].[BKM])))
WHERE [Ziel].[MitteBetrKm] IS NOT NULL
ORDER BY [Ziel].[VonKm]
Hi guys I am trying to join tables here, I want to add table called Table2 so that students from that table are displayed too. The thing which is confusing is I already have joins in this query, so how should add another join so that students from that Table2 are displayed as well, without breaking the existing code . Also, there is no way I can check output
The ID varables are stsidno in stTable 1, sidno in Table2, scsidno in table schedprd
Here's the code:
String selS = "select distinct stdistrict,stschool,stsidno,"
+ " sname as name,stgrade,"
+ "S.recnum as recnum, S.stldate as stldate,scsec,sctea,sccor,scgrade,scclsprd,scgrdprd,"
+ "case when P.scchangestartdate is null then C.clstart else "
+ "P.scchangestartdate end as scchangestartdate, "
+ "case when S.stedate is null or S.stedate<C.clstart "
+ "then C.clstart else S.stedate end as stedate "
+ "from stTable1 as S join schedprd as P on "
+ "(scyear=styear and scdistrict=stdistrict and scschool=stschool "
+ "and stsidno=scsidno and (scsec is not null and scsec<>'')) "
+ "left outer join calendar as C on (C.clyear=S.styear and "
+ "C.cldistrict=S.stdistrict and C.clschool=S.stschool and C.cltype='10') "
+ "where styear=? and stdistrict=? ";
You could UNION Table1 and Table2 together in a Common Table Expression (CTE) and then reference the CTE instead of Table1 in your query, like below:
WITH CTE
AS
(
SELECT *
FROM Table1
UNION
SELECT *
FROM Table2
)
select distinct
stdistrict,
stschool,
stsidno,
sname as name,
stgrade,
S.recnum as recnum,
S.stldate as stldate,
scsec,
sctea,
sccor,
scgrade,
scclsprd,
scgrdprd,
case when P.scchangestartdate is null then C.clstart else P.scchangestartdate end as scchangestartdate,
case when S.stedate is null or S.stedate<C.clstart then C.clstart else S.stedate end as stedate
from CTE as S
join schedprd as P on (scyear=styear and scdistrict=stdistrict and scschool=stschool and stsidno=scsidno and (scsec is not null and scsec<>''))
left outer join calendar as C on (C.clyear=S.styear and C.cldistrict=S.stdistrict and C.clschool=S.stschool and C.cltype='10')
where styear=? and stdistrict=?;
This SQL is returning the record count of table Dims instead returning the record count of table BIDdetails. How can I fix?
BIDReportSearch.CommandText = ("SELECT BIDdetails.Origin, BIDdetails.Destination,
Round(Sum(Dims.ChargeableWeight)) as CWeight, count(BIDdetails.Origin) as NoOfShpt
FROM BIDdetails LEFT JOIN DIMS ON BidDetails.BID=Dims.BID
where BIDdetails.OrgCountry<>'AE' and BIDdetails.DestCountry='AE' and
BIDdetails.ClosingDate>=#" & dtpBIDfrom.Value & "# and BIDdetails.ClosingDate<=#" &
dtpBIDto.Value & "# GROUP BY BIDdetails.Origin, BIDdetails.Destination
ORDER BY Round(Sum(Dims.ChargeableWeight)) DESC")
The expression:
count(BIDdetails.Origin)
simply counts the number of non-NULL values of BIDdetails.Origin in each group. Because you are actually grouping by the field, that would be the number of rows in each group.
You can get what you want in most databases by using count(distinct) on a unique identifier. Alas, MS Access doesn't support count(distinct) so such a query is much harder to write in Access. You can get just the count field by doing:
SELECT BIDdetails.Origin, BIDdetails.Destination, count(*) as NoOfShpt
FROM BIDdetails
where BIDdetails.OrgCountry <> 'AE' and BIDdetails.DestCountry='AE' and
BIDdetails.ClosingDate>=#" & dtpBIDfrom.Value & "# and BIDdetails.ClosingDate<=#" & dtpBIDto.Value & "#
GROUP BY BIDdetails.Origin, BIDdetails.Destination;
And then combining the results either in your application or by joining this query back into the original one.
EDIT:
This is your original query:
SELECT d.Origin, d.Destination,
Round(Sum(Dims.ChargeableWeight)) as CWeight, count(d.Origin) as NoOfShpt
FROM BIDdetails as d LEFT JOIN
DIMS
ON BidDetails.BID=Dims.BID
where d.OrgCountry <> 'AE' and d.DestCountry='AE' and
d.ClosingDate> = #" & d.Value & "# and d.ClosingDate<=#" & dtpBIDto.Value & "#
GROUP BY d.Origin, d.Destination
ORDER BY Round(Sum(Dims.ChargeableWeight)) DESC
There is another approach, where you aggregate first by the details and then again. I think that is easier in this case:
SELECT Origin, Destination, SUM(CWeight) as CWeight, COUNT(*) as NumShip
FROM (SELECT d.id, d.Origin, d.Destination,
Round(Sum(Dims.ChargeableWeight)) as CWeight, count(d.Origin) as NoOfShpt
FROM BIDdetails as d LEFT JOIN
DIMS
ON BidDetails.BID = Dims.BID
where d.OrgCountry <> 'AE' and d.DestCountry='AE' and
d.ClosingDate> = #" & d.Value & "# and d.ClosingDate<=#" & dtpBIDto.Value & "#
GROUP BY d.id, d.Origin, d.Destination
) as d
GROUP BY Origin, Destination
ORDER BY Round(Sum(CWeight)) DESC;
d.id refers to whatever the unique id is for what you want to count.
I am attempting to SELECT rows from a table using a query like this
SELECT pminf_member, pminf_schmem
, pminf_date, pminf_fund
, pminf_cont, pminf_rate
, pminf_matrix
FROM pe_minvf
WHERE (pminf_member = 4380)
AND (pminf_schmem = 'M')
AND (pminf_date <= '03/30/2011')
AND (pminf_date =
(SELECT MAX(pminf_date) AS Expr1
FROM pe_minvf AS pe_minvf_1
WHERE (pminf_member = 4380)
)
)
AND (pminf_fund = 'LIFESTYLE')
What I should be getting from my subquery (I think) is a date of '01/01/2011' but when I run my query I am getting no results back.
If I replace the subquery with the hardcoded date I get the correct rows returned. For example
SELECT pminf_member, pminf_schmem
, pminf_date, pminf_fund
, pminf_cont, pminf_rate
, pminf_matrix
FROM pe_minvf
WHERE (pminf_member = 4380)
AND (pminf_schmem = 'M')
AND (pminf_date <= '03/30/2011')
AND (pminf_date = '01/01/2011')
AND (pminf_fund = 'LIFESTYLE')
This query returns the correct results.
Any ideas why the subquery is not returning the max date or if it is, why am I getting no rows back?
Thanks,
Tristan
You filter on different conditions in your queries.
It's pminf_fund = 'LIFESTYLE' in the subquery but pminf_schmem = 'M' in the outer query.
Also, you limit the date in the outer query and don't do it in the subquery.
If you just need the most recent record up to '03/30/2011', use this:
SELECT TOP 1
pminf_member, pminf_schmem, pminf_date, pminf_fund, pminf_cont, pminf_rate, pminf_matrix
FROM pe_minvf
WHERE pminf_member = 4380
AND pminf_schmem = 'M'
AND pminf_fund = 'LIFESTYLE'
AND pminf_date <= '03/30/2011'
ORDER BY
pminf_date DESC
SELECT pminf_member, pminf_schmem
, pminf_date, pminf_fund
, pminf_cont, pminf_rate
, pminf_matrix
FROM pe_minvf
WHERE (pminf_member = 4380)
AND (pminf_schmem = 'M')
AND (pminf_date =
(SELECT MAX(pminf_date) AS Expr1
FROM pe_minvf AS p
WHERE (p.pminf_member = 4380) AND
p.pminf_date <= '03/30/2011'
)
)
AND (pminf_fund = 'LIFESTYLE')
The query:
SELECT MAX(pminf_date) AS Expr
FROM pe_minvf AS pe_minvf_1
WHERE (pminf_member = 4380)
;
returns '01/01/2011' or something else?
Perhaps you want the same conditions on the subquery as in th emain query:
SELECT MAX(pminf_date) AS Expr
FROM pe_minvf AS pe_minvf_1
WHERE (pminf_member = 4380)
AND (pminf_schmem = 'M')
use a subquery to limit rows returned instead of the where clause. Use this as the subquery:
(SELECT MAX(pminf_date) AS Expr1
FROM pe_minvf AS pe_minvf_1
WHERE (pminf_member = 4380)
Keep the query basically the same...
Select same_fields_as you_did_before
from pe_minvf
inner join
(SELECT MAX(pminf_date) AS Maxdate, tablekey
FROM pe_minvf AS pe_minvf_1
WHERE pminf_member = 4380) a on a.tablekey = pe_minvf.table_key
where same_where_clause_you_had
Make sense? I wasn't sure what your table_key was on pe_minvf...you'll have to insert that yourself. I find using subqueires adn inner joining to them is a more effective way of limiting rows then having a subquery in your where clause
Twelfth!
Thanks for the proper syntax... I used it to resolve my similar problem de-jur (of-the-day)
Unless I am wrong, what I have below will work.. If it doesn't I will fix it here...
In the example below the data fields name have been cleansed but the syntax worked very fast.
By the way, there are 20,480 distinct device_id
declare
#BegDate varchar(20)=(select cast(CONVERT(VARCHAR(20), getdate()-2,101) as varchar(20)) + ' 10:59:59 PM')
,#EndDate varchar(20)=(select cast(CONVERT(VARCHAR(20), getdate()-0,101) as varchar(20)) + ' 11:00:00 PM')
select f1.ABC_ConfigProcStatusID,f1.DeviceID,f1.DBfilename ,f1.LastUpdatedDate
from dbo.ABC_ConfigProcStatus f1
inner join
(select distinct DeviceID,max(LastUpdatedDate) as max_DeviceIDdte
from dbo.ABC_ConfigProcStatus
where [Status]=2
and DeviceID not in(select ExclusionDeviceIDs from ABC_ConfigDeviceIDExclusionList)
group by DeviceID) f2
on f2.max_DeviceIDdte = f1.LastUpdatedDate
where [Status]=2
and f2.DeviceID = f1.DeviceID
and f1.DeviceID not in(select ExclusionDeviceIDs from ABC_ConfigDeviceIDExclusionList)
and LastUpdatedDate between #BegDate and #EndDate
and left(upper(f1.DeviceID),3) in ('XYZ','ZKO')
order by f1.LastUpdatedDate