SQL count query not working - sql

I have problem with this query:
SELECT Ordre.Objet, Count(Ordre.Objet) AS CompteDeObjet
FROM Ordre INNER JOIN Avis ON Ordre.[Ordre SAP] = Avis.[Ordre SAP]
GROUP BY Ordre.Objet, Avis.[Date Appel], Ordre.Objet
HAVING (((Avis.[Date Appel])>#8/1/2011# And (Avis.[Date Appel])<#10/20/2011#) AND ((Ordre.Objet) Is Not Null));
That I generated using Access 2003. it should count the number of items of each kind in the Object column but it only shows a count of one per different item...
Can't seem to figure out how to make this work.
[EDIT]
Considering the first two answers, I changed my code to the following, but I still get the same result:
SELECT Ordre.Objet, Count(Ordre.Objet) AS CompteDeObjet
FROM Ordre INNER JOIN Avis ON Ordre.[Ordre SAP] = Avis.[Ordre SAP]
WHERE (((Avis.[Date Appel])>#8/1/2011# And (Avis.[Date Appel])<#10/20/2011#) AND ((Ordre.Objet) Is Not Null))
GROUP BY Ordre.Objet;
[EDIT #2]
here is a sample of my data:
Ordre SAP Objet
11147212 Simplex
11147214 Simplex
11147215 Simplex
11147216 Simplex
11147225 Simplex
11147240 Auto Level
11147243
11147247 CANOPY
11147259 Capteur
And here is what the query from the last edit gives me:
Auto Level 1
CANOPY 1
Capteur 1
Simplex 1
All of my data is included in the date range specified in the query.
Sorry, i don't know how to show this in a proper table, I'm new here...

The query will give one row / count per item you GROUP BY.
You are grouping on:
GROUP BY Ordre.Objet, Avis.[Date Appel], Ordre.Objet
So, you will get one cound for each Objet / Date Appel combination

Try moving what is in the HAVING clause to the WHERE clause. HAVING filters on grouped items, it may be stopping the query from counting the items properly.

Ok, so I figured out what my problem was:
I have way more Ordres than I have Avis and not all avis have an ordre attached. My query somehow only counts the objects that have an Avis attached to it (because of the JOIN clause?)
so while testing, I just randomly placed lots of different values to random record in the order table. it just so happened that I put one of each on Ordres that had corresponding Avis...
Silly me :)
Thanks everyone though, help is always apreciated

Related

Looking for guidance on my sql query that apparently includes an array

Quite new to sql, and looking for help on what i'm doing wrong.
With the code below, i'm getting the error "cannot access field value on a value with type array<struct> at [1:30]"
The "audience size value" comes from the dataset public_campaigns where as the engagement rate comes from the data set public_instagram_channels
I think the dataset that's causing the issue here is the public_campaigns.
thanks in advance for your help!
SELECT creator_audience_size.value, AVG(engagement_rate/1000000) AS avgER
FROM `public_instagram_channels` AS pic
JOIN `public_campaigns`AS pc
ON pic.id=pc.id
GROUP BY creator_audience_size.value
This is to do with the type of one of the columns using REPEATED mode.
In Google BigQuery you have to use UNNEST on these repeated columns to get their individual values in the result set.
It's unclear from what you've posted which column is the repeated type - looking at the table definition for public_instagram_channels and public_campaigns will reveal this - look for the word REPEATED in the Mode column of the table definition.
Once you've found it, include UNNEST in your query, as per this untested example:
SELECT creator_audience_size.value, AVG(engagement_rate/1000000) AS avgER
FROM `public_instagram_channels` AS pic,
UNNEST(`column_name`) AS whatever_you_want
JOIN `public_campaigns`AS pc ON pic.id = pc.id
GROUP BY creator_audience_size.value

Microsoft Access Query - Can't select records when adding a date to query

I am trying to compare two tables in MS Access 2010, and select records from one table (tmp_import_table) which don't exist in the second table (referrals). This works fine with the following query:
SELECT tmp_import_table.F2, tmp_import_table.F12, tmp_import_table.F13, tmp_import_table.RefDate
FROM tmp_import_table LEFT JOIN referrals ON tmp_import_table.[F2] = referrals.[ext_referral_no]
WHERE (((referrals.ext_referral_no) Is Null));
and results in the following dataset:
However, I now need to add a second criteria to the WHERE clause in the query, and select only records which occur after a certain date, which is stored in referrals.referral_date (date/time field) I have written the following query:
SELECT tmp_import_table.F2, tmp_import_table.F12, tmp_import_table.F13, tmp_import_table.RefDate
FROM tmp_import_table LEFT JOIN referrals ON tmp_import_table.[F2] = referrals.[ext_referral_no]
WHERE (((referrals.ext_referral_no) Is Null) AND ((referrals.referral_date)>#9/10/2014#));
But the query always ends with an empty dataset! I've tried all sorts of permutations of it, but always end up with the same empty result! In addition I've tried swearing, banging my head against the wall, and alcohol, but none of these seem to have worked either...
Can anybody spot an obvious problem with my query?
Thanks for looking!
Seb
You are doing left join and selecting tmp_import_table.RefDate in the first query. But filtering by referrals.referral_date in the second one which may be/are NULLs. Change to:
....AND ((tmp_import_table.referral_date)>#9/10/2014#));

Grouping results within SQL

I was thinking about doing this in crystal, but am thinking about doing it another way now. This is the way I was thinking about doing it before. Count by group in crystal reports
I am pulling by transactions and need a count of unique people, but in the report they want to show the count of individual people and then show their services below as shown in the image. What I'd like to do is somehow get a count of unique users that I could just throw in at the bottom. Crystal won't allow me to do a count by group and users will have duplicates in the format they want it displayed. I am hopping that I can group it in the code then just add it to the bottom of the report. I hope I'm getting across what I'm trying to accomplish. If I can somehow just add the total of unique users at the bottom of the report it will finish it for me. Thanks in advance.
select
distinct p.patient_id,
pa.fname as 'Patient',
p.clinic_id,
p.service_id,
p.program_id,
p.protocol_id,
p.discharge_reason,
p.date_discharged
from patient_assignment p
join patient pa
on p.patient_id = pa.patient_id
where p.program_id not in ('TEST', 'SA', 'INTAKE' ) and (p.date_discharged between '2013-01-01 00:00:00.000' and '2013-06-01 00:00:00.000')
and p.patient_id not in ('00000004', '00001667', '00020354')
This is too long for a comment.
SQL Queries have fixed columns. You can't "just throw" a different type of row at the bottom. Although there are SQL solutions (such as concatenating all the fields to make a single row), these are not very palatable.
Instead, here are some other ways.
You can run another query to get the count.
You can query the "result" set to get the count (perhaps after fetching all the rows).
You can do some minor coding work in the application.

SQL - How to insert a subquery into a query in order to retrieve unique values

I am writing reports using Report Builder 3, and I need some help with an sql query to get unique values.
Using the following sample data:
I need to be able to get one single value for feeBudRec returned for each feeRef. The value of each feeBudRec is always the same for each individual feeRef (eg for every data row for feeRef LR01 will have a feeBudRec of 1177).
The reason why I need to get a single feeBudRec value for each feeRef is that I need to be able to total the feeBudRec value for each feeRef in a feePin (eg for feePin LEE, I need to total the feeBudRec values for LR01 and PS01, which should be 1177 + 1957 to get a total of 3134; but if I don't have unique values for feeBudRec, it will add the values for each row, which would bring back a total of 11756 for the 8 LEE rows).
My experience with writing SQL queries is very limited, but from searching the internet, it looks like I'll need to put in a subquery into my SQL query in order to get a single unique feeBudRec figure for each feeRef, and that a subquery that gets a minimum feeBudRec value for each feeRef should work for me.
Based on examples I've found, I think the following subquery should work:
SELECT a.feeRef, a.feeBudRec
FROM (
SELECT uvw_EarnerInfo.feeRef, Min(uvw_EarnerInfo.feeBudRec) as AvailableTime
FROM uvw_EarnerInfo
GROUP BY
uvw_EarnerInfo.feeRef
) as x INNER JOIN uvw_EarnerInfo as a ON a.feeRef = x.feeRef AND a.feeBudRec = x.AvailableTime;
The problem is that I have no idea how to insert that subquery into the query I'm using to produce the report (as follows):
SELECT
uvw_EarnerInfo.feeRef
,uvw_EarnerInfo.PersonName
,uvw_EarnerInfo.PersonSurname
,uvw_EarnerInfo.feePin
,uvw_RB_TimeLedger.TimeDate
,uvw_RB_TimeLedger.matRef
,uvw_RB_TimeLedger.TimeTypeCode
,uvw_RB_TimeLedger.TimeCharge
,uvw_RB_TimeLedger.TimeElapsed
,uvw_WoffTimeByTime.WoffMins
,uvw_WoffTimeByTime.WoffCharge
,uvw_EarnerInfo.feeBudRec
,uvw_EarnerInfo.personOccupation
FROM
uvw_RB_TimeLedger
LEFT OUTER JOIN uvw_WoffTimeByTime
ON uvw_RB_TimeLedger.TimeId = uvw_WoffTimeByTime.TimeId
RIGHT OUTER JOIN uvw_EarnerInfo
ON uvw_EarnerInfo.feeRef = uvw_RB_TimeLedger.feeRef
WHERE
uvw_RB_TimeLedger.TimeDate >= #TimeDate
AND uvw_RB_TimeLedger.TimeDate <= #TimeDate2
If that subquery will get the correct results, can anyone please help me with inserting it into my report query. Otherwise, can anyone let me know what I will need to do to get a unique feeBudRec value for each feeRef?
Depends on the exact schema, but assuming the uvw_EarnerInfo lists the Pin, Ref, and Rec without duplicates, try adding an extra column (after personOccupation) on the end of your query such as :
feeBudRecSum = (Select SUM(FeeBudRec) From uvw_EarnerInfo x
where x.feePin = uvw_EarnerInfo.feePin
Group By x.FeePin)
Note that you would not Sum these values in your report. This column should have the total you are looking for.
The key to Report Builder is to get your query correct from the offset and let the wizard then structure your report for you. It takes all the hard work out of structuring your report manually.
I haven't used Report Builder for a while now but in the query builder of the report displaying the graphical representation of your query you should be able to drag and drop columns in and out of the query set. Dragging a column upwards and out of the box (showing your columns) would have the effect of causing your report to break on this column.
If you restructure this way you will probably have to run the report generator again to regenerate the report and restructure it.
Once you are happy with the structure you can then begin to add the summary columns.

Slow Query - Help with Optimization

Hey guys. This is a follow-on from this question:
After getting the right data and making some tweaks based on requests from business, I've now got this mini-beast on my hands. This query should return the total number of new jobseeker registrations and the number of new uploaded CV's:
SELECT COUNT(j.jobseeker_id) as new_registrations,
(
SELECT
COUNT(c.cv_id)
FROM
tb_cv as c, tb_jobseeker, tb_industry
WHERE
UNIX_TIMESTAMP(c.created_at) >= '1241125200'
AND
UNIX_TIMESTAMP(c.created_at) <= '1243717200'
AND
tb_jobseeker.industry_id = tb_industry.industry_id
)
AS uploaded_cvs
FROM
tb_jobseeker as j, tb_industry as i
WHERE
j.created_at BETWEEN '2009-05-01' AND '2009-05-31'
AND
i.industry_id = j.industry_id
GROUP BY i.description, MONTH(j.created_at)
Notes:
- The two values in the UNIX TIMESTAMP functions are passed in as parameters from the report module in our backend.
Every time I run it, MySQL chokes and lingers silently into the ether of the Interweb.
Help is appreciated.
Update: Hey guys. Thanks a lot for all the thoughtful and helpful comments. I'm only 2 weeks into my role here, so I'm still learning the schema. So, this query is somewhere between a thumbsuck and an educated guess. Will start to answer all your questions now.
tb_cv is not connected to the other tables in the sub-query. I guess this is the root cause for the slow query. It causes generation of a Cartesian product, yielding a lot more rows than you probably need.
Other than that I'd say you need indexes on tb_jobseeker.created_at, tb_cv.created_at and tb_industry.industry_id, and you might want to get rid of the UNIX_TIMESTAMP() calls in the sub-query since they prevent use of an index. Use BETWEEN and the actual field values instead.
Here is my attempt at understanding your query and writing a better version. I guess you want to get the count of new jobseeker registrations and new uploaded CVs per month per industry:
SELECT
i.industry_id,
i.description,
MONTH(j.created_at) AS month_created,
YEAR(j.created_at) AS year_created,
COUNT(DISTINCT j.jobseeker_id) AS new_registrations,
COUNT(cv.cv_id) AS uploaded_cvs
FROM
tb_cv AS cv
INNER JOIN tb_jobseeker AS j ON j.jobseeker_id = cv.jobseeker_id
INNER JOIN tb_industry AS i ON i.industry_id = j.industry_id
WHERE
j.created_at BETWEEN '2009-05-01' AND '2009-05-31'
AND cv.created_at BETWEEN '2009-05-01' AND '2009-05-31'
GROUP BY
i.industry_id,
i.description,
MONTH(j.created_at),
YEAR(j.created_at)
A few things I noticed while writing the query:
you GROUP BY values you don't output in the end. Why? (I've added the grouped field to the output list.)
you JOIN three tables in the sub-query while only ever using values from one of them. Why? I don't see what it would be good for, other than filtering out CV records that don't have a jobseeker or an industry attached — which I find hard to imagine. (I've removed the entire sub-query and used a simple COUNT instead.)
Your sub-query returns the same value every time. Did you maybe mean to correlate it in some way, to the industry maybe?.
The sub-query runs once for every record in a grouped query without being wrapped in an aggregate function.
First and foremost it may be worth moving the 'UNIX_TIMESTAMP' conversions to the other side of the equation (that is, perform a reverse function on the literal timestamp values at the other side of the >= and <=). That'll avoid the inner query having to perform the conversions for every record, rather than once for the query.
Also, why does the uploaded_cvs query not have any where clause linking it to the outer query? Am I missing something here?