SQL Count not working correctly - sql

I am trying to use the query below to get a list of software programs and the count of computers it is installed on. So the output would be like
Count (computers) Software
55 Microsoft Outlook
When I use the query below it gives me a count but I don't think its the count I am looking for. So if the software is installed on 55 computers it would return that count. TIA
SELECT COUNT(c.Name0),
a.DisplayName0
FROM v_GS_ADD_REMOVE_PROGRAMS a,
v_R_System c
WHERE A.DisplayName0 NOT LIKE 'hotfix for%'
AND A.DisplayName0 NOT LIKE 'Security Update for%'
GROUP BY a.DisplayName0
ORDER BY COUNT(c.Name0)

It looks like you're missing a join predicate between the two tables. Is the reference to v_R_System necessary?
If not you can just use
SELECT COUNT(*),
a.DisplayName0
FROM v_GS_ADD_REMOVE_PROGRAMS a
WHERE A.DisplayName0 NOT LIKE 'hotfix for%'
AND A.DisplayName0 NOT LIKE 'Security Update for%'
GROUP BY a.DisplayName0
ORDER BY COUNT(*);
If it is necessary you will need to add a join predicate between the tables.

Related

"Your query does not include the specified expression..."

I have tried endless things to get this to work and it seems to break over and over again and not work. I'm trying to GROUP BY product after I have calculated the field quantity returned/quantity ordered, but I get the error
your query does not include the specified expression 'quantity_returned/quantity_ordered' as part of an aggregate function.
I do not want to GROUP BY quantity_returned, quantity_ordered, and product, I only want to GROUP BY product.
Here's what my SQL looks like currently...
SELECT
quantity_returned/quantity_ordered AS percentage_returned,
quantity_returned,
quantity_ordered,
returns_fact.product
FROM
Customer_dimension
INNER JOIN
(
Product_dimension
INNER JOIN
(
Day_dimension
INNER JOIN
returns_fact
ON Day_dimension.day_key = returns_fact.day_key
)
ON Product_dimension.product_key = returns_fact.product_key
)
ON Customer_dimension.customer_key = returns_fact.customer_key
GROUP BY returns_fact.product;
When you use a group by you need to actually include everything in your select that isn't a aggregate function.
I have no idea how your tables are set up, but I am throwing a blind dart. If you provide fields in each of the 4 tables someone will be better able to help.
SELECT returns_fact.product, count(quantity_returned), count(quantity_ordered), count(quantity_returned)/count(quantity_ordered) as percentage returned

Sum(IIF( including results with 0 count

Hey All i am using sum iff to return a count based on multiple criteria.
i am basically running a report on calls recieved per site, however i need sites with 0 calls included in the result set, with the value of 0 or even Null, if they have no calls for that week.
only issue is that my where cluase has only included sites that have had calls in the week
Any ideas.
Code:
SELECT
d.sitename,
count(c.Chargeablecalls) AS All_Calls,
SUM(IIf(c.ChargeableCalls Like "Chargeable",1,0)) AS Chargeable_calls,
d.sitetype
FROM
(Callstatus AS s LEFT JOIN statusconversion AS c ON s.description=c.reportheading)
INNER JOIN sitedetails AS d ON s.zone=d.zone
WHERE s.date_loaded BETWEEN
(SELECT reportdate FROM reportMonth) AND (SELECT priorweek FROM reportMonth)
GROUP BY d.sitename, d.sitetype;
You need a RIGHT JOIN for sitedetails in order to get all the sites even those with no calls.
You may need to do the first half of query separately and then use that query in the main query.
create a new query - qryCallStatus:
SELECT DISTINCT zone, description
FROM Callstatus, reportMonth
WHERE
Callstatus.date_loaded BETWEEN reportMonth.reportdate AND reportMonth.priorweek;
Then change your output query to:
SELECT
d.sitename,
count(c.Chargeablecalls) AS All_Calls,
SUM(IIf(c.ChargeableCalls Like "Chargeable",1,0)) AS Chargeable_calls,
d.sitetype
FROM
(sitedetails AS d LEFT JOIN qryCallStatus AS s ON d.zone=s.zone)
LEFT JOIN statusconversion AS c ON s.description=c.reportheading
GROUP BY d.sitename, d.sitetype;

How do you explicitly show rows which have count(*) equal to 0

The query I'm running in DB2
select yrb_customer.name,
yrb_customer.city,
CASE count(*) WHEN 0 THEN 0 ELSE count(*) END as #UniClubs
from yrb_member, yrb_customer
where yrb_member.cid = yrb_customer.cid and yrb_member.club like '%Club%'
group by yrb_customer.name, yrb_customer.city order by count(*)
Shows me people which are part of clubs which has the word 'Club' in it, and it shows how many such clubs they are part of (#UniClubs) along with their name and City. However for students who are not part of such a club, I would still like for them to show up but just have 0 instead of them being hidden which is what's happening right now. I cannot get this functionality with count(*). Can somebody shed some light? I can explain further if the above is not clear enough.
I'm not familiar with DB2 so I'm taking a stab in the dark, but try this:
select yrb_customer.name,
yrb_customer.city,
CASE WHEN yrb_member.club like '%Club% THEN count(*) ELSE 0 END as #UniClubs
from yrb_member, yrb_customer
where yrb_member.cid = yrb_customer.cid
group by yrb_customer.name, yrb_customer.city order by count(*)
Basically you don't want to filter for %Club% in your WHERE clause because you want ALL rows to come back.
You're going to want a LEFT JOIN:
SELECT yrb_customer.name, yrb_customer.city,
COUNT(yrb_member.club) as clubCount
FROM yrb_customer
LEFT JOIN yrb_member
ON yrb_member.cid = yrb_customer.cid
AND yrb_member.club LIKE '%Club%
GROUP BY yrb_customer.name, yrb_customer.city
ORDER BY clubCount
Also, if the tuple (yrb_customer.name, yrb_customer.city) is unique (or is supposed to be - are you counting all students with the same name as the same person?), you might get better performance out of the following:
SELECT yrb_customer.name, yrb_customer.city,
COALESCE(club.count, 0)
FROM yrb_customer
LEFT JOIN (SELECT cid, COUNT(*) as count
FROM yrb_member
WHERE club LIKE '%Club%
GROUP BY cid) club
ON club.cid = yrb_customer.cid
ORDER BY club.count
The reason that your original results were being hidden was because in your original query, you have an implicit inner join, which of course requires matching rows. The implicit-join syntax (comma-separated FROM clause) is great for inner (regular) joins, but is terrible for left-joins, which is what you really needed. The use of the implicit-join syntax (and certain types of related filtering in the WHERE clause) is considered deprecated.

SQL Access query speed

I have the following query in my Access 2003 database:
SELECT
Projet.OTP AS OTP,
NumeroDA,
SUM(Quantite*PrixReelCommande) AS PrixTotal,
FIRST(Fournisseur1) AS Fournisseur,
FIRST(Projet.NumeroCommandeReservation) AS NumeroCommande,
FIRST(Projet.GestionContrat) AS GestionContrat,
FIRST(Projet.Acheteur) AS Acheteur,
MIN(DateLivraisonContractuelle) AS DateLivraisonContrat,
MAX(DateFournisseurLivraison) AS DateLivraisonFournisseur,
FIRST(InfoProjet.NomInstallation) AS NomInstallation,
FIRST(InfoProjet.TitreMandat) AS TitreMandat
FROM Projet LEFT JOIN InfoProjet ON Projet.OTP=InfoProjet.OTP
WHERE NumeroDA Like "#*" And NumeroDA IN (
SELECT NumeroDA FROM Projet
WHERE NumeroCommandeReservation="" Or NumeroCommandeReservation Is Null Or NumeroCommandeReservation="0"
)
GROUP BY Projet.OTP, Projet.NumeroDA
ORDER BY Projet.OTP, Projet.NumeroDA
The table Projet has ~2500 rows and InfoProjet has only 200 rows. Opening either of this table in Access takes less than 1 second. However, executing the above query takes more than 5 seconds.
I would like to know if there is anything I can do to improve the performance of this query. Is there something in the query that I should avoid performance-wise? Or am I just under Access limitations? I guess that using Like in the subquery doesn't help, but there must be something else that slows down the query.
Since you're not using any Distincts in the subquery, could you simplify it a little by taking that part out? (I can't test this right now though, so I'm not entirely sure it would give the same results)
SELECT
Projet.OTP AS OTP,
NumeroDA,
SUM(Quantite*PrixReelCommande) AS PrixTotal,
FIRST(Fournisseur1) AS Fournisseur,
FIRST(Projet.NumeroCommandeReservation) AS NumeroCommande,
FIRST(Projet.GestionContrat) AS GestionContrat,
FIRST(Projet.Acheteur) AS Acheteur,
MIN(DateLivraisonContractuelle) AS DateLivraisonContrat,
MAX(DateFournisseurLivraison) AS DateLivraisonFournisseur,
FIRST(InfoProjet.NomInstallation) AS NomInstallation,
FIRST(InfoProjet.TitreMandat) AS TitreMandat
FROM Projet LEFT JOIN InfoProjet ON Projet.OTP=InfoProjet.OTP
WHERE NumeroDA Like "#*" And (
NumeroCommandeReservation="" Or
NumeroCommandeReservation Is Null Or
NumeroCommandeReservation="0")
GROUP BY Projet.OTP, Projet.NumeroDA
ORDER BY Projet.OTP, Projet.NumeroDA
Try running this and see how many rows it returns:
SELECT COUNT(*)
FROM Projet LEFT JOIN InfoProjet ON Projet.OTP=InfoProjet.OTP
WHERE NumeroDA Like "#*" And NumeroDA IN (
SELECT NumeroDA FROM Projet
WHERE NumeroCommandeReservation=""
Or NumeroCommandeReservation Is Null
Or NumeroCommandeReservation="0"
)
Reason: Join may be returning more rows that you'd expect, but as you have only MAX/MIN/FIRST Aggregates you may not notice.

Access 2003 Query Dilemma

I am, having difficulty with multiple values returning for each user. I have tried variations of Select Distinct to no avail. I need my code to only retun one value per userID.
SELECT Roster.UserID,
EventLog.Type,
IIf([EventLog]![LogType] Like "Acc*" And [EventLog]![Action] Like "Wri*",[EventLog]![Date],Date()-183) AS [Review Date]
FROM EventLog
INNER JOIN Roster
ON EventLog.UserID = Roster.UserID
GROUP BY Roster.UserID,
EventLog.Type,
IIf([EventLog]![LogType] Like "Acc*" And [EventLog]![Action] Like "Wri*",[EventLog]![Date],Date()-183)
HAVING (((EventLog.Type) Like "Att*"));
The code is returning both values from the IIf when they meet the first criteria. How can I limit to one or the other?
You're getting multiple values per user because you've listed multiple fields in your GROUP BY clause:
GROUP BY Roster.UserID,
EventLog.Type,
IIf([EventLog]![LogType] Like "Acc*" And
[EventLog]![Action] Like "Wri*",[EventLog]![Date],Date()-183)
I'm not sure why you're grouping at all, as you're not performing any aggregate functions. Would SELECT DISTINCT work?
Thanks for the feedback folks. Basedon what Beth replied and cleaning up my tables and querys to send a copy of the dBasethe problem seemed to work itself out with a small addition of code.
SELECT Roster.UserID,
EventLog.Type,
Max(IIf(EventLog!LogType Like "Acc*" And EventLog!Action Like "Wri*",EventLog!Date,Date()-183)) AS [Review Date]
FROM EventLog
INNER JOIN Roster
ON EventLog.UserID = Roster.UserID
GROUP BY Roster.UserID,
EventLog.Type
HAVING (((EventLog.Type) Like "Att*"));
The clean up of the multi fields from Beth worked a treat!!!