Access Count of Rows Where Field is not Null - sql

I need to count rows where the value of Master.[Date BP] is not Null - any ideas how I would do this?
I tried this but it doesn't seem to work.
SELECT Master.[Date BP], Count(Master.[Date BP]) AS CountOfField,
FROM Master
GROUP BY Master.[Date BP];

SELECT Count([Date BP]) AS CountOfField
FROM Master

Using count is the right idea. You just need to remove the group by clause, as you want a single answer. Additionally, you have a redundant comma at the end of the select list:
SELECT Count(Master.[Date BP]) AS CountOfField
FROM Master

The above answers are correct. Just in case you may face other problems with other aggregate functions, aggregate functions in SQL will ignore the null value.
Reference: https://msdn.microsoft.com/en-us/library/ms173454.aspx

Related

Grouping data and keeping only distinct values in SQL

Is it possible to group and the following data in pgsql:
(TL;DR: Note the similar target entries for the two print_names qz.M2 and qz.M1)
print_name
target
qz.R
q3zA
qz.S
NULL
qz.M1
q2zA
qz.M1
q1zA
qz.M2
q2zA
qz.M2
q1zA
in such a way that the distinct values of target are still in the result while the doubling of qz.M* is avoided.
The result desired would therefore be:
print_name
target
qz.R
q3zA
qz.S
NULL
qz.M1
q2zA
qz.M2
q1zA
I tried:
SELECT min(target) FROM Table GROUP BY print_name;
However, this of course only yields one of two entries in target.
Thank you for your help!
I dont think this is achievable without casing specific print_name if you want consistent answer.
SELECT t.print_name
FROM Table t
CASE
WHEN t.print_name = 'qz.M1' THEN max(t.target)
WHEN t.print_name = 'qz.M2' THEN min(t.target)
ELSE t.target END as Target
GROUP BY t.print_name
Your desired results would seem to indicate just a simple aggregate:
select print_name, Max(target) target
from t
group by print_name
Note your sample data does not include any reliable method or sorting, max() will be based on string ordering.

Access SQL GROUP BY problem (eg. tbl_Produktion.ID not part of the aggregation-function)

I want to group by two columns, however MS Access won't let me do it.
Here is the code I wrote:
SELECT
tbl_Produktion.Datum, tbl_Produktion.Schichtleiter,
tbl_Produktion.ProduktionsID, tbl_Produktion.Linie,
tbl_Produktion.Schicht, tbl_Produktion.Anzahl_Schichten_P,
tbl_Produktion.Schichtteam, tbl_Produktion.Von, tbl_Produktion.Bis,
tbl_Produktion.Pause, tbl_Produktion.Kunde, tbl_Produktion.TeileNr,
tbl_Produktion.FormNr, tbl_Produktion.LabyNr,
SUM(tbl_Produktion.Stueckzahl_Prod),
tbl_Produktion.Stueckzahl_Ausschuss, tbl_Produktion.Ausschussgrund,
tbl_Produktion.Kommentar, tbl_Produktion.StvSchichtleiter,
tbl_Produktion.Von2, tbl_Produktion.Bis2, tbl_Produktion.Pause2,
tbl_Produktion.Arbeiter3, tbl_Produktion.Von3, tbl_Produktion.Bis3,
tbl_Produktion.Pause3, tbl_Produktion.Arbeiter4,
tbl_Produktion.Von4, tbl_Produktion.Bis4, tbl_Produktion.Pause4,
tbl_Produktion.Leiharbeiter5, tbl_Produktion.Von5,
tbl_Produktion.Bis5, tbl_Produktion.Pause5,
tbl_Produktion.Leiharbeiter6, tbl_Produktion.Von6,
tbl_Produktion.Bis6, tbl_Produktion.Pause6, tbl_Produktion.Muster
FROM
tbl_Personal
INNER JOIN
tbl_Produktion ON tbl_Personal.PersID = tbl_Produktion.Schichtleiter
GROUP BY
tbl_Produktion.Datum, tbl_Produktion.Schichtleiter;
It works when I group it by all the columns, but not like this.
The error message say that the rest of the columns aren't part of the aggregation-function (translated from german to english as best as I could).
PS.: I also need the sum of "tbl_Produktion.Stueckzahl_Prod" therefore I tried using the SUM function (couldn't try it yet).
Have you tried something along these lines?
SELECT
tbl_Produktion.Datum, tbl_Produktion.Schichtleiter,
MAX(tbl_Produktion.ProduktionsID), MAX(tbl_Produktion.Linie),
MAX(tbl_Produktion.Schicht), MAX(tbl_Produktion.Anzahl_Schichten_P),
MAX(tbl_Produktion.Schichtteam), MAX(tbl_Produktion.Von), MAX(tbl_Produktion.Bis),
SUM(tbl_Produktion.Stueckzahl_Prod)
FROM
tbl_Personal
INNER JOIN
tbl_Produktion ON tbl_Personal.PersID = tbl_Produktion.Schichtleiter
GROUP BY
tbl_Produktion.Datum, tbl_Produktion.Schichtleiter;
I have used the MAX function for all the data except the two items you specify in the GROUP BY and the one where you desire the SUM. I took the liberty of leaving out mush of your data just to get started.
Using the MAX function turns out to be a convenient workaround when the data item is known to be unique within each group. We cannot know your data or your itent, so we cannot tell you whether MAX will yield the results you need.
If you use an aggregation function in the select clause, you must group by every column that you're selecting that's not an aggregation. If you don't want to do that for some reason (perhaps it changes the output of the aggregation in way that you don't intend) you either must think of an aggregate to use (pick a value. Average? Max? Min?) or just do two selects, one for the aggregate, and one for the non-aggregates. But, then, you have to decide how to get the non-aggregated fields that make sense for the aggregate (or show them all in a table, I suppose?)

Add a Percent of Total Column in Access Query

I have the following query:
SELECT [3-2017].[Dealer#], Sum([3-2017].Balance) AS SumOfBalance
FROM [3-2017]
GROUP BY [3-2017].[Dealer#];
I want to add a column that returns the percent of grand total for each dealer#. I think I need another single-row query with the totals and join or union somehow, but I'm completely lost.
I've looked through a few different posts and this is the top result, but it doesn't solve my problem, unfortunately.
Really best and easiest done in a report. However, try:
SELECT [3-2017].[Dealer#], Sum([3-2017].Balance) AS SumDealerBal,
(SELECT Sum(Balance) FROM [3-2017]) AS SumBalance, SumDealerBal/SumBalance AS DealerPct
FROM [3-2017]
GROUP BY [3-2017].[Dealer#];
Advise no spaces or special character/punctuation (underscore is only exception) in any names. Better would be DealerNum or Dealer_Num.

designedly big value in SQL

Ok, I have to put null values last. The query should run under Oracle and MySQL.
I've already came up with
ORDER BY
CASE WHEN some_table.ord IS NULL THEN 9999999999 ELSE some_table.ord END
I should use value > max(some_table.ord) instead of 9999999999.
I think subquery to determine this value is too ugly here.
If this was C++ I can use some macro like INT_MAX for this purpose. Can you name its cross-DBMS SQL twin?
UPDATE
the question is if can I put something .. beautiful instead of 9999999999, so that query will work both in Oracle and MySQL,
not how to put null values last
Use an extra column for the null flag:
order by
case when some_table.ord is null then 2 else 1 end ,
some_table.ord
Or, if you have enough knowledge of the values that this column can take, just hard-code a number that is larger than anything in there:
order by coalesce(some_table.ord, 9999999999)
In Oracle, it's simply
ORDER BY some_table.ord NULLS LAST
Something like the following might work:
SELECT S.VAL1, S.VAL2, S.VAL3, COALESCE(S.ORD, O.MAX_ORD+1) AS ORD
FROM SOME_TABLE S,
(SELECT MAX(ORDER) AS MAX_ORD FROM SOME_TABLE) O
WHERE S.whatever = whichever AND
S.something <> something_else
ORDER BY ORD
Not sure if MySQL allows sub-queries in the FROM list. The idea here is to avoid the use of a magic value to handle the NULL case.
Share and enjoy.

Group by SQL statement

So I got this statement, which works fine:
SELECT MAX(patient_history_date_bio) AS med_date, medication_name
FROM biological
WHERE patient_id = 12)
GROUP BY medication_name
But, I would like to have the corresponding medication_dose also. So I type this up
SELECT MAX(patient_history_date_bio) AS med_date, medication_name, medication_dose
FROM biological
WHERE (patient_id = 12)
GROUP BY medication_name
But, it gives me an error saying:
"coumn 'biological.medication_dose' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.".
So I try adding medication_dose to the GROUP BY clause, but then it gives me extra rows that I don't want.
I would like to get the latest row for each medication in my table. (The latest row is determined by the max function, getting the latest date).
How do I fix this problem?
Use:
SELECT b.medication_name,
b.patient_history_date_bio AS med_date,
b.medication_dose
FROM BIOLOGICAL b
JOIN (SELECT y.medication_name,
MAX(y.patient_history_date_bio) AS max_date
FROM BIOLOGICAL y
GROUP BY y.medication_name) x ON x.medication_name = b.medication_name
AND x.max_date = b.patient_history_date_bio
WHERE b.patient_id = ?
If you really have to, as one quick workaround, you can apply an aggregate function to your medication_dose such as MAX(medication_dose).
However note that this is normally an indication that you are either building the query incorrectly, or that you need to refactor/normalize your database schema. In your case, it looks like you are tackling the query incorrectly. The correct approach should the one suggested by OMG Poinies in another answer.
You may be interested in checking out the following interesting article which describes the reasons behind this error:
But WHY Must That Column Be Contained in an Aggregate Function or the GROUP BY clause?
You need to put max(medication_dose) in your select. Group by returns a result set that contains distinct values for fields in your group by clause, so apparently you have multiple records that have the same medication_name, but different doses, so you are getting two results.
By putting in max(medication_dose) it will return the maximum dose value for each medication_name. You can use any aggregate function on dose (max, min, avg, sum, etc.)