SQL Server: Sum(column) and count(column) in Select and Join statement - sql-server

I'm trying to query how many transaction each loyaltyID column has in AnthemTxns_Jr and what the total of all of their transactions adds up to. Right now, when I run this script, it says,
Cannot find either column "dbo" or the user-defined function or aggregate "dbo.AnthemTxns_JR.count", or the name is ambiguous
Code:
Select DISTINCT
dbo.ANTHEM_IDS_JR.loyaltyID,
dbo.ANTHEM_IDS_JR.Military_Type,,
dbo.ANTHEM_IDS_JR.Military_Date,
dbo.AnthemTxns_JR.count(CheckTotal),
dbo.AnthemTxns_JR.sum(CheckTotal)
From
dbo.ANTHEM_IDS_JR
JOIN
dbo.AnthemTxns_JR ON dbo.ANTHEM_IDS_JR.loyaltyID = dbo.AnthemTxns_JR.loyaltyID
WHERE
Military_Type = 'Active Duty'
AND ACTIVE = 1
AND datalength(dbo.ANTHEM_IDS_JR.Military_Date) > 0
ORDER BY
loyaltyID;

Try this... It looks like you have it a bit mixed up in the select statement
Select DISTINCT
dbo.ANTHEM_IDS_JR.loyaltyID,
dbo.ANTHEM_IDS_JR.Military_Type,
dbo.ANTHEM_IDS_JR.Military_Date,
count(dbo.AnthemTxns_JR.CheckTotal) as CheckTotalCount,
sum(dbo.AnthemTxns_JR.CheckTotal) as CheckTotalSum
From
dbo.ANTHEM_IDS_JR
JOIN
dbo.AnthemTxns_JR ON dbo.ANTHEM_IDS_JR.loyaltyID = dbo.AnthemTxns_JR.loyaltyID
WHERE
Military_Type = 'Active Duty'
AND ACTIVE = 1
AND datalength(dbo.ANTHEM_IDS_JR.Military_Date) > 0
Group by
dbo.ANTHEM_IDS_JR.loyaltyID,
dbo.ANTHEM_IDS_JR.Military_Type,
dbo.ANTHEM_IDS_JR.Military_Date
ORDER BY
loyaltyID;

Related

Tsql query need to find duplicates and join tables to determine which ones to delete

I have this query that works and returns correct duplicate data.
select [serverName], ActiveYN, count(servername)
from dbo.FarmStats_Server
group by [serverName], ActiveYN
having (count(servername) > 1)
returns 260 rows.
What I need to do is a bit more complicated.
SELECT
dbo.FarmStats_Farm.FarmName,
dbo.FarmStats_Server.ServerName,
dbo.FarmStats_Server.obsDT, dbo.FarmStats_Server.ActiveYN
FROM
dbo.FarmStats_Farm
INNER JOIN
dbo.FarmStats_Server ON dbo.FarmStats_Farm.FarmID = dbo.FarmStats_Server.FarmIDFK
GROUP BY
dbo.FarmStats_Farm.FarmName, dbo.FarmStats_Server.ServerName, dbo.FarmStats_Server.obsDT, dbo.FarmStats_Server.ActiveYN
HAVING
(COUNT(dbo.FarmStats_Server.ServerName) > 1)
This query returns no results. I am missing something fundamentally.
End goal will be to delete one of the duplicates.
Thanks for your help.
You can Use this in subquery as below:
SELECT
dbo.FarmStats_Farm.FarmName,
dbo.FarmStats_Server.ServerName,
dbo.FarmStats_Server.obsDT,
dbo.FarmStats_Server.ActiveYN
FROM dbo.FarmStats_Farm
INNER JOIN dbo.FarmStats_Server fs
ON dbo.FarmStats_Farm.FarmID =
dbo.FarmStats_Server.FarmIDFK
WHERE EXISTS (SELECT
[serverName],
ActiveYN
FROM dbo.FarmStats_Server
WHERE servername = fs.servername
AND activeyn = fs.activeyn
GROUP BY [serverName],
ActiveYN
HAVING (COUNT(servername) > 1))

COUNT field incorrect or syntax error

What would be the error when I get following error message
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[07002]: [Microsoft][ODBC Driver 11 for SQL Server]COUNT field incorrect or syntax error'...
This is the query I'm using
$sql = $pdo->prepare("SELECT stockamount, stockname, stockbalance.stockid, SUM(ABS(reservationtransaction.stockquantity)) AS reservedamount FROM stockbalance
JOIN stock ON stockbalance.stockid = stock.stockid
LEFT JOIN reservationtransaction ON reservationtransaction.articleid = :artid
WHERE stockbalance.articleid = :artid AND ((changeddate > DATEADD(yy,-1,GETDATE()) AND inventorydate > DATEADD(yy,-1,GETDATE())) OR stockbalance.stockamount <> 0)
GROUP BY stockbalance.stockid");
$sql->bindValue(':artid', $productId);
$sql->execute();
I have searched questions in SO, but no one was similar or helpful.
Thanks in advance.
Edit: This query is working fine when executing it with Microsoft SQL Server Management Studio, but when using PDO, I'm getting the error.
The number of parameters specified in SQLBindParameter was less than
the number of parameters in the SQL statement contained in
*StatementText. SQLBindParameter was called with ParameterValuePtr set to a null pointer, StrLen_or_IndPtr not set to SQL_NULL_DATA or
SQL_DATA_AT_EXEC, and InputOutputType not set to SQL_PARAM_OUTPUT, so
that the number of parameters specified in SQLBindParameter was
greater than the number of parameters in the SQL statement contained
in *StatementText. SQLExecute Function
placeholders must have unique names even if they have the same value
$sql = $pdo->prepare("SELECT stockamount, stockname, stockbalance.stockid, SUM(ABS(reservationtransaction.stockquantity)) AS reservedamount FROM stockbalance
JOIN stock ON stockbalance.stockid = stock.stockid
LEFT JOIN reservationtransaction ON reservationtransaction.articleid = :artid
WHERE stockbalance.articleid = :artid2 AND ((changeddate > DATEADD(yy,-1,GETDATE()) AND inventorydate > DATEADD(yy,-1,GETDATE())) OR stockbalance.stockamount <> 0)
GROUP BY stockbalance.stockid");
$sql->bindValue(':artid', $productId);
$sql->bindValue(':artid2', $productId);
$sql->execute();
Another possibility, if you want to avoid supplying data multiple times (replace the datatype of #artid with the correct data type):
$sql = $pdo->prepare("DECLARE #artid int = :artid
SELECT stockamount, stockname, stockbalance.stockid, SUM(ABS(reservationtransaction.stockquantity)) AS reservedamount FROM stockbalance
JOIN stock ON stockbalance.stockid = stock.stockid
LEFT JOIN reservationtransaction ON reservationtransaction.articleid = #artid
WHERE stockbalance.articleid = #artid AND ((changeddate > DATEADD(yy,-1,GETDATE()) AND inventorydate > DATEADD(yy,-1,GETDATE())) OR stockbalance.stockamount <> 0)
GROUP BY stockbalance.stockid");
$sql->bindValue(':artid', $productId);
$sql->execute();
This will only work in an RDBMS that supports DECLARE statements.
All the columns that are not in any arithmetic function must go in the GROUP BY clause. see below:
SELECT stockamount,
stockname,
stockbalance.stockid,
Sum(Abs(reservationtransaction.stockquantity)) AS reservedamount
FROM stockbalance
INNER JOIN stock
ON stockbalance.stockid = stock.stockid
LEFT JOIN reservationtransaction
ON reservationtransaction.articleid = :artid
WHERE stockbalance.articleid = :artid
AND ( ( changeddate > Dateadd(yy, -1, Getdate())
AND inventorydate > Dateadd(yy, -1, Getdate()) )
OR stockbalance.stockamount <> 0 )
GROUP BY stockamount,
stockname,
stockbalance.stockid
While GROUP BY is often the culprit for a COUNT issue, I ran into the subject error in SSRS and it was due to a mismatch between the SSRS dataset query and the parameters. The resolution was to ensure each WHERE in the query had a corresponding parameter for the dataset. (I had missed one.)
We had this error when a Django filter statement was trying to substitute more parameters in a query than could be handled by the DB binary. Our query looked roughly like this:
select name, age from Employee where emp_id in (%s)
from a Django statement
Employee.objects.filter(emp_id__in=employee_ids)
The list of emp_id was about 2,100 elements. (The character length of the params substituted was about 10,500).
The hack was to filter in parts and recombine the subsets.

GROUP BY error in SQL Server 2012

I'm getting this error
Column 'tbl_user.u_id' is invalid in the select list because it is not
contained in either an aggregate function or the GROUP BY clause.
When I'm doing this query
SELECT *
FROM
tbl_user
JOIN
tbl_assign_role ON tbl_user.u_id = tbl_assign_role.tar_owner_id
WHERE
is_active = 1
AND u_id != 1
AND tar_is_deleted = 0
GROUP BY
tbl_assign_role.tar_owner_id
ORDER BY
tbl_user.u_updated_date DESC
Strongly agreed with #Dai
According to me, you should read first the role of "Group By". Here in your query there is no any aggregate function used, so there is no case here to use "Group By".
Do this, to continue removing duplicates while not needing the group by:
SELECT DISTINCT --[INSERT NEEDED COLUMNS HERE]
FROM
tbl_user
JOIN
tbl_assign_role ON tbl_user.u_id = tbl_assign_role.tar_owner_id
WHERE
is_active = 1
AND u_id != 1
AND tar_is_deleted = 0
ORDER BY
tbl_user.u_updated_date DESC

No column name was specified for column 2 of 'a' error

I have a MySQL query and I ran it working fine but same query showing error in SQL Server.
SQL Server query:
SELECT
COUNT(*) cnt
FROM
(SELECT DISTINCT
tc_id, MAX(exn_time), STATUS
FROM
release_details a, tc_details b
WHERE
a.project = b.project
AND a.tc_id = b.tc_name
AND logicaldel = 0
AND a.project = 'test'
GROUP BY
tc_id, STATUS) a
WHERE
a.status = 'PASS';
Error:
No column name was specified for column 2 of 'a'.
How do I modify the above query?
Use the Alias name for your inner query.You are getting the MAX(exn_time) but not specified the name for that column that's why throwing the error. And you can use the Joins to the tables to make it more readable.
SELECT COUNT(*) cnt
FROM (
SELECT DISTINCT
tc_id,
MAX(exn_time) AS Maxtime ,
STATUS
FROM
release_details a JOIN tc_details b
ON a.project= b.project
AND a.tc_id = b.tc_name
WHERE
logicaldel = 0
AND a.project ='test'
GROUP BY
tc_id,
STATUS
) a
WHERE a.status='PASS';
You missed to give Alias name inside subquery
Also as mentioned by Marc_s you need to use proper Inner Join, keep the join condition ON clause and move the filter to where clause
SELECT Count(*) cnt
FROM (SELECT DISTINCT tc_id,
Max(exn_time) Max_exn_time,
STATUS
FROM release_details a
INNER JOIN tc_details b
ON a.project = b.project
AND a.tc_id = b.tc_name
WHERE a.project = 'test'
AND logicaldel = 0
GROUP BY tc_id,
STATUS) a
WHERE a.status = 'PASS';
Your issue is obviously that your second column in the resultset a doesn't have an alias.
You can rewrite the whole query to this for the same result:
SELECT
COUNT(DISTINCT tc_id) cnt
FROM
release_details a
JOIN
tc_details b
ON
a.project = b.project
AND a.tc_id = b.tc_name
WHERE
logicaldel = 0
AND a.project = 'test'
AND STATUS = 'PASS'
Since STATUS only can have the value 'PASS', MAX(exn_time) is not helping your counting, DISTINCT should not be used in the beginning of a SELECT when using group by like in your case, it is redundant

Join subquery with min

I'm pulling my hair out over a subquery that I'm using to avoid about 100 duplicates (out of about 40k records). The records that are duplicated are showing up because they have 2 dates in h2.datecreated for a valid reason, so I can't just scrub the data.
I'm trying to get only the earliest date to return. The first subquery (that starts with "select distinct address_id", with the MIN) works fine on it's own...no duplicates are returned. So it would seem that the left join (or just plain join...I've tried that too) couldn't possibly see the second h2.datecreated, since it doesn't even show up in the subquery. But when I run the whole query, it's returning 2 values for some ipc.mfgid's, one with the h2.datecreated that I want, and the other one that I don't want.
I know it's got to be something really simple, or something that just isn't possible. It really seems like it should work! This is MSSQL. Thanks!
select distinct ipc.mfgid as IPC, h2.datecreated,
case when ad.Address is null
then ad.buildingname end as Address, cast(trace.name as varchar)
+ '-' + cast(trace.Number as varchar) as ONT,
c.ACCOUNT_Id,
case when h.datecreated is not null then h.datecreated
else h2.datecreated end as Install
from equipmentjoin as ipc
left join historyjoin as h on ipc.id = h.EQUIPMENT_Id
and h.type like 'add'
left join circuitjoin as c on ipc.ADDRESS_Id = c.ADDRESS_Id
and c.GRADE_Code like '%hpna%'
join (select distinct address_id, equipment_id,
min(datecreated) as datecreated, comment
from history where comment like 'MAC: 5%' group by equipment_id, address_id, comment)
as h2 on c.address_id = h2.address_id
left join (select car.id, infport.name, carport.number, car.PCIRCUITGROUP_Id
from circuit as car (NOLOCK)
join port as carport (NOLOCK) on car.id = carport.CIRCUIT_Id
and carport.name like 'lead%'
and car.GRADE_Id = 29
join circuit as inf (NOLOCK) on car.CCIRCUITGROUP_Id = inf.PCIRCUITGROUP_Id
join port as infport (NOLOCK) on inf.id = infport.CIRCUIT_Id
and infport.name like '%olt%' )
as trace on c.ccircuitgroup_id = trace.pcircuitgroup_id
join addressjoin as ad (NOLOCK) on ipc.address_id = ad.id
The typical approach to only getting the lowest row is one of the following. You didn't bother to specify what version of SQL Server you're using, what you want to do with ties, and I have little interest to try to work this into your complex query, so I'll show you an abstract simplification for different versions.
SQL Server 2000
SELECT x.grouping_column, x.min_column, x.other_columns ...
FROM dbo.foo AS x
INNER JOIN
(
SELECT grouping_column, min_column = MIN(min_column)
FROM dbo.foo GROUP BY grouping_column
) AS y
ON x.grouping_column = y.grouping_column
AND x.min_column = y.min_column;
SQL Server 2005+
;WITH x AS
(
SELECT grouping_column, min_column, other_columns,
rn = ROW_NUMBER() OVER (ORDER BY min_column)
FROM dbo.foo
)
SELECT grouping_column, min_column, other_columns
FROM x
WHERE rn = 1;
This subqery:
select distinct address_id, equipment_id,
min(datecreated) as datecreated, comment
from history where comment like 'MAC: 5%' group by equipment_id, address_id, comment
Probably will return multiple rows because the comment is not guaranteed to be the same.
Try this instead:
CROSS APPLY (
SELECT TOP 1 H2.DateCreated, H2.Comment -- H2.Equipment_id wasn't used
FROM History H2
WHERE
H2.Comment LIKE 'MAC: 5%'
AND C.Address_ID = H2.Address_ID
ORDER BY DateCreated
) H2
Switch that to OUTER APPLY in case you want rows that don't have a matching desired history entry.

Resources