sql count function with subquery - sql

here is my query
select narr,vocno,count(*)
from KontenLedger
WHERE VOCDT>'2018-07-01'
group by narr,vocno
having count(*)<'3'
actually if i wright as i given above ,the result which calculates two fields ('narr' and 'vocno') if i remove the field ('narr') answer is correct. i need to view the field 'narr' also without counting

Without knowing your database, nor having some limited sample date, nor expected output?
SELECT
vocno,
COUNT(*) AS total,
MAX(narr) AS max_narr
FROM KontenLedger
WHERE vocdt > '2018-07-01'
GROUP BY vocno
HAVING COUNT(*) < 3

Related

SQL Why am I getting the invalid identifier error?

I am trying to use columns that I created in this query to create another column.
Let me first my messy query. The query looks like this:
SELECT tb.team, tb.player, tb.type, tb.date, ToChar(Current Date-1, 'DD-MON-YY') as yesterday,
CASE WHEN to_date(tb.date) = yesterday then 1 else 0 end dateindicator,
FROM (
COUNT DISTINCT(*)
FROM TABLE_A, dual
where dateindicator = 1
Group by tb.team
)
What I am trying to do here is:
creating a column with "Yesterday's date"
Using the "Yesterday" column to create another column called dateindicator indicating each row is yesterday's data or not.
then using that dateindicator, I want to count the distinct number of player for each team that has 1 of the dateindicator column.
But I am getting the "invalid identifier" error. I am new to this oracle SQL, and trying to learn here.
You cannot use an Alias in your Select statement.
see here: SQL: Alias Column Name for Use in CASE Statement
you need to use the full toChar(.. in the CASE WHEN.
Also:
Your WHERE-condition (Line 5) doesnt belong there.. it should be:
SELECT DISTINCT .>. FROM .>. WHERE. you have to specify the table first. then you can filter it with where.
If I follow your explanation correctly: for each team, you want to count the number of players whose date column is yesterday.
If so, you can just filter and aggregate:
select team, count(*) as cnt
from mytable
where mydate >= trunc(sysdate) - 1 and mydate < trunc(sysdate)
group by team
This assumes that the dates are stored in column mydate, that is of date datatype.
I am unsure what you mean by counting distinct players; presumably, a given player appears just once per team, so I used count(*). If you really need to, you can change that to count(distinct player).
Finally: if you want to allow teams where no player matches, you can move the filtering logic within the aggregate function:
select team,
sum(case when mydate >= trunc(sysdate) - 1 and mydate < trunc(sysdate) then 1 else 0 end) as cnt
from mytable
group by team

get the latest records

I am currently still on my SQL educational journey and need some help!
The query I have is as below;
SELECT
Audit_Non_Conformance_Records.kf_ID_Client_Reference_Number,
Audit_Non_Conformance_Records.TimeStamp_Creation,
Audit_Non_Conformance_Records.Clause,
Audit_Non_Conformance_Records.NC_type,
Audit_Non_Conformance_Records.NC_Rect_Received,
Audit_Non_Conformance_Records.Audit_Num
FROM Audit_Non_Conformance_Records
I am trying to tweak this to show only the most recent results based on Audit_Non_Conformance_Records.TimeStamp_Creation
I have tried using MAX() but all this does is shows the latest date for all records.
basically the results of the above give me this;
But I only need the result with the date 02/10/2019 as this is the latest result. There may be multiple results however. So for example if 02/10/2019 had never happened I would need all of the idividual recirds from the 14/10/2019 ones.
Does that make any sense at all?
You can filter with a subquery:
SELECT
kf_ID_Client_Reference_Number,
TimeStamp_Creation,
Clause,
NC_type,
NC_Rect_Received,
Audit_Num
FROM Audit_Non_Conformance_Records a
where TimeStamp_Creation = (
select max(TimeStamp_Creation)
from Audit_Non_Conformance_Records
)
This will give you all whose TimeStamp_Creation is equal to the greater value available in the table.
If you want all records that have the greatest day (exluding time), then you can do:
SELECT
kf_ID_Client_Reference_Number,
TimeStamp_Creation,
Clause,
NC_type,
NC_Rect_Received,
Audit_Num
FROM Audit_Non_Conformance_Records a
where cast(TimeStamp_Creation as date) = (
select cast(max(TimeStamp_Creation) as date)
from Audit_Non_Conformance_Records
)
Edit
If you want the latest record per refNumber, then you can correlate the subquery, like so:
SELECT
kf_ID_Client_Reference_Number,
TimeStamp_Creation,
Clause,
NC_type,
NC_Rect_Received,
Audit_Num
FROM Audit_Non_Conformance_Records a
where TimeStamp_Creation = (
select max(TimeStamp_Creation)
from Audit_Non_Conformance_Records a1
where a1.refNumber = a.refNumber
)
For performance, you want an index on (refNumber, TimeStamp_Creation).
If you want the latest date in SQL Server, you can express this as:
SELECT TOP (1) WITH TIES ancr.kf_ID_Client_Reference_Number,
ancr.TimeStamp_Creation,
ancr.Clause,
ancr.NC_type,
ancr.NC_Rect_Received,
ancr.Audit_Num
FROM Audit_Non_Conformance_Records ancr
ORDER BY CONVERT(date, ancr.TimeStamp_Creation) DESC;
SQL Server is pretty good about handling dates with conversions, so I would not be surprised if this used an index on TimeStamp_Creation.

Returning single records per month

I have a use case function that needs to returns a single row only for every end of month.
I tried using select distinct and it is showing multiple records for the same end of month
SELECT DISTINCT CASE
WHEN eff_interest_balance < 0.01 THEN trial_balance_date
WHEN date_paid < trial_balance_date THEN date_paid
END as A
, period
FROM dbo.Intpayments[enter image description here][1]
WHERE loan_number = 60023
ORDER BY period ASC
Each row should return single date for each month
Distinct is returning unique rows, not grouping them. You are looking to aggregate rows. This means using some combination of aggregate functions and group by.
What your current query is missing is some sort of logic for aggregating the rows that are in the same period. Do you want to compare the sum of these values? The min, the max?
In any case, the basic idea of aggregating and grouping would look like this - I don't think this summing is what you want, but the query shows the basic idea of aggregating and grouping:
SELECT
period
, SUM(eff_interest_balance) AS SumOfBalance
FROM dbo.Intpayments
WHERE loan_number = 60023
GROUP BY period

Group by in t-sql not displaying single result

See the image below. I have a table, tbl_AccountTransaction in which I have 10 rows. The lower most table having columsn AccountTransactionId, AgreementId an so on. Now what i want is to get a single row, that is sum of all amount of the agreement id. Say here I have agreement id =23 but when I ran my query its giving me two rows instead of single column, since there is nano or microsecond difference in between the time of insertion.
So i need a way that will give me row 1550 | 23 | 2011-03-21
Update
I have update my query to this
SELECT Sum(Amount) as Amount,AgreementID, StatementDate
FROM tbl_AccountTranscation
Where TranscationDate is null
GROUP BY AgreementID,Convert(date,StatementDate,101)
but still getting the same error
Msg 8120, Level 16, State 1, Line 1
Column 'tbl_AccountTranscation.StatementDate' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Your group by clause is in error
group by agreementid, convert(date,statementdate,101)
This makes it group by the date (without time) of the statementdate column. Whereas the original is grouping by the statementdate (including time) then for each row of the output, applying the stripping of time information.
To be clear, you weren't supposed to change the SELECT clause
SELECT Sum(Amount) as Amount,AgreementID, Convert(date,StatementDate,101)
FROM tbl_AccountTranscation
Where TranscationDate is null
GROUP BY AgreementID,Convert(date,StatementDate,101)
Because you have a Group By StatementDate.
In your example you have 2 StatementDates:
2011-03-21 14:38:59.470
2011-03-21 14:38:59.487
Change your query in the Group by section instead of StatementDate to be:
Convert(Date, StatementDate, 101)
Have you tried to
Group by (Convert(date,...)
instead of the StatementDate
You are close. You need to combine your two approaches. This should do it:
SELECT Sum(Amount) as Amount,AgreementID, Convert(date,StatementDate,101)
FROM tbl_AccountTranscation
Where TranscationDate is null
GROUP BY AgreementID,Convert(date,StatementDate,101)
If you never need the time, the perhaps you need to change the datatype, so you don't have to do alot of unnecessary converting in most queries. SQL Server 2008 has a date datatype that doesn't include the time. In earlier versions you could add an additional date column that is automatically generated to strip out the time companent so all the dates are like the format of '2011-01-01 00:00:00:000' then you can do date comparisons directly having only had to do the conversion once. This would allow you to have both the actual datetime and just the date.
You should group by DATEPART(..., StatementDate)
Ref: http://msdn.microsoft.com/en-us/library/ms174420.aspx

SQL code needed for Query

I need SQL code for a query I need to do in Access. I have a table with multiple fields but I only need 2 fields for the query. 1 is a date field. let's call that one DateField. the other is a field that contains text, let's call lit TextField. I need a query that returns the following:
The COUNT of DateField (i.e. how many there are regardless of what the value is)
The COUNT of TextField WHERE its value = "ThisText"
The COUNT of TextField WHERE its value = "ThatText"
Results GROUP BY Year
the same query again (will be a separate Q) but with results GROUP BY Month
Many thanks in advance for all your wonderful help.
I believe you can only SELECT a given aggregate function once per per query. That is to say you cannot request the COUNT two different fields in a single query. Here's the reference for the count function in JET SQL. At best you can count the number of non-NULL values of a certain field in a grouped result set under some WHERE clause.
SELECT YEAR/MONTH(DateField), COUNT(DateField),
SUM(IIF(TextField='ThisText', 1, 0)),
SUM(IIF(TextField='ThatText', 1, 0))
FROM MyTable
GROUP BY YEAR/MONTH(DateField)
How about:
SELECT
Year
,COUNT(DISTINCT DateField) AS NumDateFields
,COUNT(CASE WHEN TextField = 'ThisText' THEN 1 END) AS ThisTextCount
,COUNT(CASE WHEN TextField = 'ThatText' THEN 1 END) AS ThisTextCount
GROUP BY Year;
Or... GROUP BY Month