Using Aggregate Function in sql - sql

Why this query is not working:-
SELECT b.byhub,
Count(awbno)
FROM (SELECT awbno,
byhub,
entrydatetime,
Max(entrydatetime)
FROM wbbooking
GROUP BY awbno,
byhub,
entrydatetime) B
INNER JOIN (SELECT refno,
Max(entrydatetime)
FROM wbmmreceiving
GROUP BY refno) R
ON B.awbno = R.refno
WHERE CONVERT(DATE, b.entrydatetime) BETWEEN '2016-10-13' AND '2016-10-13'
GROUP BY b.byhub
After Execute this query I have obtain this type of Error:-
Msg 8155, Level 16, State 2, Line 2
No column name was specified for column 4 of 'b'.
Msg 8155, Level 16, State 2, Line 3
No column name was specified for column 2 of 'r'.

The errors occur, because you have not specified a name for the aggregate column Max(entrydatetime). Change it to Max(entrydatetime) AS max_entrydatetime.
This query is a bit strange. The subquery B selects entrydatetime as well as Max(entrydatetime). But since entrydatetime is included in the group by list, Max(entrydatetime) will always be the same as entrydattetime.
If you want the last entrydatetime per awbno and byhub, then don't group by entrydatetime and only include it as Max(entrydatetime) in the select list. If you really want to group by this date column, then don't include it as Max(entrydatetime).
What is the purpose of the second subquery? None of its returned columns are used except for joining. Is it needed for the count?
Why include a where-clause in the outer query? If you include it in the first subquery, it is more efficient and the entrydatetime column needs not to be returned any more.

Just specify column names for your subqueries, like this:
SELECT b.byhub,
Count(awbno)
FROM (SELECT awbno,
byhub,
entrydatetime,
Max(entrydatetime) max_entrydatetime
FROM wbbooking
GROUP BY awbno,
byhub,
entrydatetime) B
INNER JOIN (SELECT refno,
Max(entrydatetime) max_entrydatetime
FROM wbmmreceiving
GROUP BY refno) R
ON B.awbno = R.refno
WHERE CONVERT(DATE, b.entrydatetime) BETWEEN '2016-10-13' AND '2016-10-13'
GROUP BY b.byhub

Related

SQL : Date condition Updated

I want to update my column depending on dates from two different table. Below is my query
UPDATE T_TRN_DEAL_DETAILS SET MATURITY_DT =
(CASE
WHEN (Select top 1 INS.INVOICE_DUE_DT as invoice_date from T_TRN_INVOICE_DETAILS IND
INNER jOIN T_TRN_INVOICE_SUMMARY INS on IND.INVOICE_ID=INS.INVOICE_ID
where IND.DEAL_ID ='1234'
order by INS.INVOICE_DUE_DT desc ) > (Select DEAL_ID,MATURITY_DT as invoice_date from T_TRN_DEAL_DETAILS WHERE DEAL_ID ='1234')
THEN (Select top 1 INS.INVOICE_DUE_DT as invoice_date from T_TRN_INVOICE_DETAILS IND
INNER jOIN T_TRN_INVOICE_SUMMARY INS on IND.INVOICE_ID=INS.INVOICE_ID
where IND.DEAL_ID ='1234'
order by INS.INVOICE_DUE_DT desc)
ELSE (Select DEAL_ID,MATURITY_DT as invoice_date from T_TRN_DEAL_DETAILS WHERE DEAL_ID ='DL18111213586')
END )
WHERE DEAL_ID ='1234'
But I am getting below error
Only one expression can be specified in the select list when the
subquery is not introduced with EXISTS
Although I am just comparing two dates.
The error is clear:
a subquery must return only one column but in your ELSE breanch you have written as follow:
(Select DEAL_ID,MATURITY_DT as invoice_date
from T_TRN_DEAL_DETAILS WHERE DEAL_ID ='DL18111213586')
So you try to return two columns. You must remove DEAL_ID column, because your MATURITY_DT is the field you want to use to update your main table.
The same error you have done in the first branch when you try to compare subqueries (>) where the second subquery returns two columns instead of one.
(Select DEAL_ID,MATURITY_DT as invoice_date
from T_TRN_DEAL_DETAILS WHERE DEAL_ID ='1234')

query data in the order of IN clause

select osmid,ST_X(shape),ST_Y(shape)
from osmpoints
where (osmpoints.osmid, osmpoints.osmtimestamp)
IN (select osmid,MAX(osmtimestamp)
from osmPoints
GROUP BY osmid
Having MAX(osmtimestamp) <= '2019-09-16T01:23:55Z'
AND osmid in ('4426786454','1861591896','1861591869','1861591895',
'4426786455','2038185115','1861591853','6797739995',
'2299605892','6797739994','1861591898','2038185111','4426786454'));
when I run this query, I get sorted rows based on osmid column.
but my question is how can I get rows in order of osmid that use in the IN clause?
You can use the same technique as shown here:
with input(idlist) as (
values (
array['4426786454','1861591896','1861591869','1861591895',
'4426786455','2038185115','1861591853','6797739995',
'2299605892','6797739994','1861591898','2038185111','4426786454']::text[])
)
select p.osmid,ST_X(shape),ST_Y(shape)
from osmpoints p
cross join input
where (p.osmid, p.osmtimestamp) IN (select osmid,MAX(osmtimestamp)
from osmPoints
cross join input
GROUP BY osmid
Having MAX(osmtimestamp) <= '2019-09-16T01:23:55Z'
AND osmid = any(idlist))
order by array_position(idlist, osmid);

Column l' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause - but it is

I have a sql subquery that does the following - it calculates some sums based on a over partition of a column. After that in I want to inner join the table with itself so that I could get the difference between dates.
The problem that it is showing is:
Column 'tblFinansijskiPodaci.DatumVal' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
The problem started when I inserted the date values in the DATEDIFF. When I insert some random date values like '2017/08/25', '2011/08/25' it works fine.
Is maybe my join in the wrong place?
This is my query:
SELECT P2.FinID, P2.Firma, P2.BrojDok, P2.DatumVal,P2.Saldo ,P2.SaldoTotal2,
IIF(P2.SaldoTotal2<0,0,IIF(P2.SaldoTotal2<1,(DATEDIFF(DAY,P2.DatumVal, b.DatumVal)),0))
AS NumberOfDays
FROM
(
SELECT P1.FinID, P1.Firma,P1.BrojDok,P1.DatumVal,P1.Saldo,P1.SaldoTotal,
IIF(P1.SaldoTotal<0,0,IIF(P1.SaldoTotal>1,1,0)) AS SaldoTotal1,
IIF(P1.SaldoTotal<0,0,IIF(P1.SaldoTotal<1,0,1)) AS SaldoTotal2
FROM
(
SELECT P.FinID,P.Firma,P.BrojDok,P.DatumVal,P.Saldo ,
SUM(Saldo) OVER (PARTITION BY BrojDok ORDER BY FinID) AS SaldoTotal
FROM
(
SELECT a.FinID, a.Firma, a.Konto,a.NazivKonta, a.NazFirme, a.BrojDok,
a.DatumVal,a.Valuta,
Sum(IIf(a.[Konto] Like '2%',a.[Duguje] -a.[Potrazuje],a.[Potrazuje] -a.[Duguje]))
AS Saldo
FROM tblFinansijskiPodaci a WHERE a.Firma = 1 AND a.Konto = 2040
AND a.Partner = 1137
GROUP BY a.FinID,a.Firma,a.NazFirme,a.Konto,a.NazivKonta,a.BrojDok,
a.DatumVal,a.Valuta,a.Duguje,a.Potrazuje
) AS P
GROUP BY FinID,Firma,BrojDok,Saldo,DatumVal
) AS P1
GROUP BY P1.FinID,P1.Firma,P1.BrojDok,P1.DatumVal,P1.Saldo,P1.SaldoTotal
) AS P2
INNER JOIN tblFinansijskiPodaci b ON b.BrojDok=P2.BrojDok
GROUP BY P2.FinID,P2.Firma,P2.BrojDok,P2.Saldo,P2.SaldoTotal,P2.SaldoTotal1,P2.SaldoTotal2,P2.DatumVal
ORDER BY BrojDok
Try to add b.DatumVal in your last GROUP BY clause.

Need a count of one column if i am having another column values multiple

I am having this query:
select qos.orgname, qos.org, qos.suborg, qos.Archive, qos.location, count(c.coe) AS DEPT, c.coe AS DEP,
qos.siteid, qos.admin as sitelead,
CASE When qos.Archive = 0 THEN 'Active'
when qos.Archive is null THEN '-'
ELSE 'Archived'
END AS STATUS
from qryOrgsite qos WITH (NOLOCK)
LEFT JOIN ltbcoe c WITH (NOLOCK) on qos.orgname = c.orgname and qos.location= c.location
group by qos.orgname, qos.location, qos.org, qos.suborg, qos.Archive, c.coe,
qos.siteid, qos.ADMIN
This gives me some records as follows:
So i want the count of "Dept" column which are active. I mean it should return only one row with Organization B and Dept as 7....e.g here the Dept column should be 7.
that means I want count of c.coe column.
The problem here is your GROUP BY is too inclusive. What the query is asking for is a count, but the results have to be unique by all of the columns in your GROUP BY. If you only want a count per orgname, you will need to do
SELECT qos.orgname, COUNT(*)
FROM qryOrgsite qos
GROUP BY qos.orgname
This essentially says that you want to count all rows by the orgname. Each column you add to the group by creates unique combinations for your COUNT. For example, if you grouped by orgname and location it would give you a roll up count for each combination of those two columns. Based on the data you show above this would result in
OrganizationB Demo-Fixe 1
OrganizationB GE CapitalP 3
OrganizationB Hadasa Plant 1
OrganizationB Mostoles Plant 1
You can wrap your query in another:
select orgname, count(*)
from (
select qos.orgname, qos.org, qos.suborg, qos.Archive, qos.location, count(c.coe) AS DEPT, c.coe AS DEP,
qos.siteid, qos.admin as sitelead,
CASE When qos.Archive = 0 THEN 'Active'
when qos.Archive is null THEN '-'
ELSE 'Archived'
END AS STATUS
from qryOrgsite qos WITH (NOLOCK)
LEFT JOIN ltbcoe c WITH (NOLOCK) on qos.orgname = c.orgname and qos.location= c.location
group by qos.orgname, qos.location, qos.org, qos.suborg, qos.Archive, c.coe,
qos.siteid, qos.ADMIN) t1
where t1.orgname = 'Organization B' and t1.STATUS = 'Active'
group by t1.orgname
guys i have got the answer.
I had to remove the department name from the group by and the select
because the count(c.coe) didnt had any effect.
Thanks for all you help

TSQL- Rollup SQL 2005

I have the following example code:
create table Details(
name varchar(20),
age int,
weight int,
recordDate Datetime)
--insert data
..query:
SELECT a.name,
a.age,
a.recordDate,
a.weight - (SELECT b.weight
FROM Details
WHERE b.recordDate = dateadd(dd, -1, a.recordDate) as subtable)
FROM Details a
GROUP BY WITH ROLLUP (a.recordDate, a.name, a.age)
I want to see the weight difference between RecordDates for each person and then record total weight different for that person and also for the age group and then grand weight gain/loss. This is not my actual table but just an example.
Problem:
It was complaining about subquery - then I had to use it as table variable: subtable.
Now it is complaining:
Msg 156, Level 15, State 1, Line 14
Incorrect syntax near the keyword 'as'.
Msg 319, Level 15, State 1, Line 18
Incorrect syntax near the keyword 'with'. If this statement is a common table expression or an xmlnamespaces clause, the previous statement must be terminated with a semicolon.
What am I missing?
Typo:
a.weight - (SELECT b.weight
FROM Details
WHERE b.recordDate = dateadd(dd, -1, a.recordDate)
..."b" is being used as a table alias, but it's not actually defined as one.
Next issue is that your GROUP BY doesn't include a.weight, and there's no aggregate function associated with it. Here's my re-write of your query:
SELECT a.name,
a.age,
a.recordDate,
SUM(a.weight - t.weight) 'weight'
FROM DETAILS a
JOIN (SELECT b.recordDate,
b.weight
FROM DETAILS b) t ON t.recordDate = DATEADD(dd, -1, a.recordDate)
GROUP BY (a.recordDate, a.name, a.age) WITH ROLLUP
Try it like this
SELECT
a.name,
a.age,
a.recordDate,
SUM(a.weight - b.weight) as WeightDiff
FROM Details a
JOIN Details b
ON (b.age = a.age
AND b.name = a.name
AND b.recordDate = dateadd(dd, -1, a.recordDate)
)
GROUP BY a.age, a.name, a.recordDate WITH ROLLUP
Don't use AS keyword. You can just directly write {(select * from blah) a}
OK, so the problem is that WITH ROLLUP isn't really the answer you're looking for. This is for creating subtotals not running totals which is what you're after, so using it will give you the total for different combinations of dates rather than a running total, which is what you're after. In the beginning, the query that you want to just get a total that gives you name, age, date and weight loss compared to yesterday is as follows:
select
a.name
,a.age
,a.recordDate
,(SELECT b.weight from Details b WHERE b.recordDate = dateadd(dd,-1,a.recordDate)) - a.weight as weightLossForToday
from details a
Keep in mind that this query will only work if you have exactly 1 record every day. If you have 2 records for a single day or the entries aren't exactly 1 day apart (ie. they include time), then it won't work. In order to get a running total working, you'll need to follow the approach from a question like this.
That should do the trick.
SELECT a.name,a.age,a.recordDate,a.weight-(SELECT b.weight
FROM Details
WHERE b.recordDate=dateadd(dd,-1,a.recordDate))
FROM Details a
GROUP BY (a.recordDate,a.name,a.age)
WITH ROLLUP