Using avg(count()) function - sql

In a dns log table, trying to use this query to get an avg. number of dns queries within a day:
select to_char(log_time, 'DD-MM-YYYY'),log_client,avg(count(*)) as nums from msint
where to_char(log_time, 'DD-MM-YYYY') = '25-09-2013' and log_client = '10.10.10.1';
and get an error "nested group function without GROUP BY"
but when I add group by log_client,log_time, get another error not a single-group group function
Maybe someone can help me with a solution. Thanks.

Please try below query, check whether the result is expected.
select
log_time,
log_client,
avg(nums) nums
From(
select
to_char(log_time, 'DD-MM-YYYY')log_time,
log_client,
count(*) over(partition by to_char(log_time, 'DD-MM-YYYY'), log_client) as nums
from msint
where
to_char(log_time, 'DD-MM-YYYY') = '25-09-2013' and
log_client = '10.10.10.1'
)x
group by log_time, log_client;

use group by along with having clause.
if possible please share your table structure so that query can be checked against it.

Related

Count of id per day using window function

I'm trying to count track_uri that are associated to a given playlist_uri in a day in a one month window and have composed the following sql:
SELECT
playlist_uri, playlist_date, track_uri, count(track_uri)
over (partition by playlist_uri, playlist_date) as count_tracks
FROM
tbl1
WHERE
_PARTITIONTIME BETWEEN '2017-09-09' AND '2017-10-09'
AND playlist_uri in (
SELECT playlist_uri from tbl2 WHERE playlist_owner = "spotify"
)
However I am getting the following output:
I instead would like it to show me the count of track_uri for each playlist_uri on each day.
Would really appreciate some help with this.
Not sure if I understand your question correctly, but if you might not need to use the window function for that:
SELECT
playlist_uri, playlist_date, COUNT(DISTINCT track_uri)
FROM
tbl1
WHERE
_PARTITIONTIME BETWEEN '2017-09-09' AND '2017-10-09'
AND playlist_uri in (
SELECT playlist_uri from tbl2 WHERE playlist_owner = "spotify"
)
GROUP BY 1, 2;

how to select the latest data?

I am using laravel 5, and I have a question for the SQL
there is the table that record the function change of employee.
I just need the latest function so I wonder to use the "group by".
but even I get the latest date, I could not get the corresponding data .
The most close to what I want is like this
DB::table('function_history')
->select(DB::raw('id_history,function_history.CUID,
max(function_change_date)as time, id_function'))
->orderBy('time','desc') ->groupBy('CUID')->get();
Thanks for your help
Ok. You just need to know the rows that corresponds to rows with max date.
Pure sql query:
select
id_history, CUID, id_function, function_change_date
from
function_history t1
join
(select max(function_change_date) as maxdt from function_history group by CUID) t2 on t1.function_change_date = t2.maxdt
Laravel query:
DB::table('function_history')->select('id_history', 'CUID', 'id_function', 'function_change_date')
->join(DB::raw('(select max(function_change_date) as maxdt from function_history group by CUID) temp'),
'temp.maxdt', '=', 'date'
)->get();
You can select all employees with their current function with this SQL query:
SELECT
function_history.*
FROM
function_history,
(
SELECT
MAX(function_change_date) as last_change_date,
CUID
FROM
function_history
GROUP BY
CUID
ORDER BY function_change_date DESC
) tmp
WHERE
function_history.CUID = tmp.CUID
AND
function_history.function_change_date = tmp.last_change_date
I’m not sure why you’re building a raw SQL query, and grouping. If you just want the latest function changes for a particular CUID, then select data and order by the date:
DB::table('function_history')
->where('CUID', '=', $cuid)
->orderBy('function_change_date')
->get();
Please use below query and convert into laravel format
SELECT
`CUID`,
MAX(`function_change_date`) AS timechange,
(SELECT
`id_function`
FROM
`function_history` fc
WHERE fc.function_change_date = MAX(f.`function_change_date`)) AS id_function
FROM
`function_history` f
GROUP BY CUID ;

Sql query using count(*) , groupby and fetching a column value simultaneously

I am been developing application in java and not much insight into sql.
Meanwhile , I have got to fetch count and username in the same query. My query goes like this :
SELECT count(*),c_user_name
FROM tra_shipment_status
WHERE i_tra_shipment_status_id IN
(SELECT MAX(i_tra_shipment_status_id)
FROM tra_shipment_status
WHERE i_status_code = '4072'
AND c_reference IN ('FILEIO0023','MIASTOFIL003')
Group By C_Reference
);
This throws me an exception "not a single-group group function"
I want the count and C_user_name of the top most row (latest one).
Can somebody please help.
If you use count(*) in the main query you also need a group by there:
SELECT count(*),c_user_name
FROM tra_shipment_status
WHERE i_tra_shipment_status_id IN
(SELECT MAX(i_tra_shipment_status_id)
FROM tra_shipment_status
WHERE i_status_code = '4072'
AND c_reference IN ('FILEIO0023','MIASTOFIL003')
Group By C_Reference
)
Group by c_user_name
When you try to include an aggregate function like count, sum, max,.. you should use group by with other unaggregated columns like c_user_name in your case. There is another thing; you say that you need the top most row but your sub query will return the top most row for each C_Reference, and to get the top most row regardless of C_Reference you should do something like the following:
SELECT count(*),c_user_name
FROM tra_shipment_status
WHERE i_tra_shipment_status_id IN
(SELECT MAX(i_tra_shipment_status_id)
FROM tra_shipment_status
WHERE i_status_code = '4072'
AND c_reference IN ('FILEIO0023','MIASTOFIL003')
);
Group By c_user_name

How to get datetime duplicate rows in SQL Server?

Im trying to find duplicate DATETIME rows in a table,
My column has datetime values such as 2015-01-11 11:24:10.000.
I must get the duplicates in 2015-01-11 11:24 type. Rest of it, not important. I can get the right value when I use SELECT with 'convert(nvarchar(16),column,121)', but when I put this in my code, I have to use 'group by' statement, so
My code is:
SELECT ID,
RECEIPT_BARCODE,
convert(nvarchar(16),TRANS_DATE,121),
PTYPE
FROM TRANSACTION_HEADER
WHERE TRANS_DATE BETWEEN '11.01.2015' AND '12.01.2015'
GROUP BY ID,RECEIPT_BARCODE,convert(nvarchar(16),TRANS_DATE,121),PTYPE
HAVING COUNT(convert(nvarchar(16),TRANS_DATE,121)) > 1
Since SQL forces me to use 'convert(nvarchar(16),TRANS_DATE,121)' in GROUP BY statement, I can't get the duplicate values.
Any idea for this?
Thanks in advance.
If you want the actual rows that are duplicated, then use window functions instead:
SELECT th.*, convert(nvarchar(16),TRANS_DATE,121)
FROM (SELECT th.*, COUNT(*) OVER (PARTITION BY convert(nvarchar(16),TRANS_DATE,121)) as cnt
FROM TRANSACTION_HEADER th
WHERE TRANS_DATE BETWEEN '11.01.2015' AND '12.01.2015'
) th
WHERE cnt > 1;
SELECT ID,RECEIPT_BARCODE,convert(nvarchar(16),TRANS_DATE,121), PTYPE ,COUNT(*)
FROM TRANSACTION_HEADER
WHERE TRANS_DATE BETWEEN '11.01.2015' AND '12.01.2015'
GROUP ID,RECEIPT_BARCODE,convert(nvarchar(16),TRANS_DATE,121), PTYPE
HAVING COUNT(*)>1;
I think you can use count(*) directly here.try the above one.

Got a error message when I try to find out which patient account have duplicated record.

When I run the script below, I got a error message "Cannot perform an aggregate function on an expression containing an aggregate or a subquery" Please provide some advice. Thanks
SELECT
CONVERT(DECIMAL(18,5),SUM(CASE WHEN PATIENT_ACCOUNT_NO IN (
SELECT PATIENT_ACCOUNT_NO
FROM STND_ENCOUNTER
GROUP BY PATIENT_ACCOUNT_NO
HAVING ( COUNT(PATIENT_ACCOUNT_NO) > 1)) THEN 0 ELSE 1 END)) dupPatNo
FROM [DBO].[STND_ENCOUNTER]
I think the error message is pretty clear. You have a sum() function with a subquery in it (albeit within a case, but that doesn't matter).
It seems that you want to choose patients that have more than one encounter, then add 0 if the patients is in the list and 1 if the patient is not. Hmmm. . . sounds like you want to count the number of patients with only one encounter.
Try using this logic instead:
select count(*)
from (select se.*, count(*) over (partition by PATIENT_ACCOUNT_NO) as NumEncounters
from dbo.stnd_encounter se
) se
where NumEncounters = 1;
As a note, the variable you are assigning is called DupPatientNo. This sounds like the number of patients that have duplicates. In that case, the query is:
select count(distinct PATIENT_ACCOUNT_NO)
from (select se.*, count(*) over (partition by PATIENT_ACCOUNT_NO) as NumEncounters
from dbo.stnd_encounter se
) se
where NumEncounters > 1;
(Or use count(*) if you want the number of encounters on duplicate patients.)
If you want to find number of PATIENT_ACCOUNT_NO that does not have any duplicates then use the following
SELECT COUNT(DISTINCT dupPatNo.PATIENT_ACCOUNT_NO)
FROM (
SELECT PATIENT_ACCOUNT_NO
FROM STND_ENCOUNTER
GROUP BY PATIENT_ACCOUNT_NO
HAVING COUNT(PATIENT_ACCOUNT_NO) = 1
) dupPatNo
If you want to find number of PATIENT_ACCOUNT_NO that have atleast one duplicate then use the following
SELECT COUNT(DISTINCT dupPatNo.PATIENT_ACCOUNT_NO)
FROM (
SELECT PATIENT_ACCOUNT_NO
FROM STND_ENCOUNTER
GROUP BY PATIENT_ACCOUNT_NO
HAVING COUNT(PATIENT_ACCOUNT_NO) > 1
) dupPatNo
Use of DISTINCT will make the query not count same item again and again
Though your query looks for first result, its not clear what you want. Hence giving query for both