Why must I fill in this Parameter value - sql

SELECT
siteapplications.Application, Count(visits.VisitId) AS CountOfVisitId
FROM
visits,
siteapplications
WHERE
visits.SiteApplicationId=siteapplications.ApplicationID
and Month([visits.VisitTime])= month and Year([visits.VisitTime])= year
GROUP BY
siteapplications.Application
ORDER BY
CountOfVisitId DESC;
Maybe a stupid question but with when I run this query I need to fill in the month, year AND CountOfVisitId??
But for CountOfVisitId I need that it is calculated (hence the query)
I don't have much experience with query's but I need this one in java
Can anyone explain or solve ....

Often, depending on your brand and version of SQL, you cannot group by a column alias, or sort by a column alias. So you might try doing ORDER BY 2 DESC instead.

As #MJB mentioned, it is fairly common that you cannot sort by a column alias. Try this (notice the change to the ORDER BY):
SELECT
siteapplications.Application, Count(visits.VisitId) AS CountOfVisitId
FROM
visits,
siteapplications
WHERE
visits.SiteApplicationId=siteapplications.ApplicationID
and Month([visits.VisitTime])= month and Year([visits.VisitTime])= year
GROUP BY
siteapplications.Application
ORDER BY
Count(visits.VisitId) DESC;

Related

Get first record based on time in PostgreSQL

DO we have a way to get first record considering the time.
example
get first record today, get first record yesterday, get first record day before yesterday ...
Note: I want to get all records considering the time
sample expected output should be
first_record_today,
first_record_yesterday,..
As I understand the question, the "first" record per day is the earliest one.
For that, we can use RANK and do the PARTITION BY the day only, truncating the time.
In the ORDER BY clause, we will sort by the time:
SELECT sub.yourdate FROM (
SELECT yourdate,
RANK() OVER
(PARTITION BY DATE_TRUNC('DAY',yourdate)
ORDER BY DATE_TRUNC('SECOND',yourdate)) rk
FROM yourtable
) AS sub
WHERE sub.rk = 1
ORDER BY sub.yourdate DESC;
In the main query, we will sort the data beginning with the latest date, meaning today's one, if available.
We can try out here: db<>fiddle
If this understanding of the question is incorrect, please let us know what to change by editing your question.
A note: Using a window function is not necessary according to your description. A shorter GROUP BY like shown in the other answer can produce the correct result, too and might be absolutely fine. I like the window function approach because this makes it easy to add further conditions or change conditions which might not be usable in a simple GROUP BY, therefore I chose this way.
EDIT because the question's author provided further information:
Here the query fetching also the first message:
SELECT sub.yourdate, sub.message FROM (
SELECT yourdate, message,
RANK() OVER (PARTITION BY DATE_TRUNC('DAY',yourdate)
ORDER BY DATE_TRUNC('SECOND',yourdate)) rk
FROM yourtable
) AS sub
WHERE sub.rk = 1
ORDER BY sub.yourdate DESC;
Or if only the message without the date should be selected:
SELECT sub.message FROM (
SELECT yourdate, message,
RANK() OVER (PARTITION BY DATE_TRUNC('DAY',yourdate)
ORDER BY DATE_TRUNC('SECOND',yourdate)) rk
FROM yourtable
) AS sub
WHERE sub.rk = 1
ORDER BY sub.yourdate DESC;
Updated fiddle here: db<>fiddle

Why are different result between use date_part and exactly date parameter query data in peroid date?

I'm try to count distinct value in some columns in a table.
i have a logic and i try to write in 2 way
But i get diffent results from this two query.
Can any one help to clarify me? I dont know what wrong is code or i think.
SQL
select count(distinct membership_id) from members_membership m
where date_part(year,m.membership_expires)>=2019
and date_part(month,m.membership_expires)>=7
and date_part(day,m.membership_expires)>=1
and date_part(year,m.membership_creationdate)<=2019
and date_part(month,m.membership_creationdate)<=7
and date_part(day,m.membership_creationdate)<=1
;
select count(distinct membership_id) from members_membership m
where m.membership_expires>='2019-07-01'
and m.membership_creationdate<='2019-07-01'
;
I actually think that this is the query you intend to run:
SELECT
COUNT(DISTINCT membership_id)
FROM members_membership m
WHERE
m.membership_expires >= '2019-07-01' AND
m.membership_creationdate < '2019-07-01';
It doesn't make sense for a membership to expire at the same moment it gets created, so if it expires on midnight of 1st-July 2019, then it should have been created strictly before that point in time.
That being said, the problem with the first query is that, e.g., the restriction on the month being on or before July would apply to every year, not just 2019. It is difficult to write a date inequality using the year, month, and day terms separately. For this reason, the second version you used is preferable. It is also sargable, meaning that an index on membership_expires or membership_creationdate can be used.
There is an issue with the first query:
select count(distinct membership_id) from members_membership m
where date_part(year,m.membership_expires)>=2019
and date_part(month,m.membership_expires)>=7
and date_part(day,m.membership_expires)>=1
and date_part(year,m.membership_creationdate)<=2019
and date_part(month,m.membership_creationdate)<=7
and date_part(day,m.membership_creationdate)<=1; -- do you think that any day is less than 1??
-- this condition will be satisfy by only 01-Jul-2019, But I think you need all the dates before 01-Jul-2019
and date_part(day,m.membership_creationdate)<=1 is culprit of the issue.
even membership_creationdate = 15-jan-1901 will not satisfy above condition.
You need to always use date functions on date columns to avoid such type of issue. (Your second query is perfectly fine)
Cheers!!
The reason could be due to a time component.
The proper comparison for the first query is:
select count(distinct membership_id)
from members_membership m
where m.membership_expires >= '2019-07-01' and
m.membership_creationdate < '2019-07-02'
--------------------------------^ not <= ---^ next day
This logic should work regardless of whether or not the "date" has a time component.

Teradata - Max value of a dataset with corresponding date

This is probably obvious, I just can't seem to get it to work right. Let's say I have a table of various servers and their CPU percentages for every day for the past year. I want to basically say:
"for every server name, show me the max CPU value that this server hit (from this dataset) and the corresponding date that it happened on"
So ideally I would get a result like:
server1 52.34% 3/16/2012
server2 48.76% 4/15/2012
server3 98.32% 6/16/2012
etc..
When I try to do this like so, I can't use a group by or else it just shows me every date:
select servername, date, max(cpu) from cpu_values group by 1,2 order by 1,2;
This of course just gives me every server and every date.. Sub-query? Partition by? Any assistance would be appreciated!
You can use the row_number() OLAP window function:
select servername
, cpu
, date
from cpu_values
qualify row_number() over (partition by servername
order by cpu desc) = 1
Notice that you do not need a GROUP BY or ORDER BY clause. The PARTITION clause is similar to a GROUP BY and the ORDER BY clause sorts the rows within each partition (in this case by descending cpu). The "=1" part selects the single row that satisfies the condition.
A subquery would be the simplest solution:
SELECT
S.Name, Peak.PeakUsage, MIN(S.Date) AS Date
FROM
ServerHistory AS S
INNER JOIN
(
SELECT
ID, MAX(CPUUsage) AS PeakUsage
FROM
ServerHistory
WHERE
Date BETWEEN X AND Y
GROUP BY
ID
) AS Peak ON S.ID = Peak.ID
GROUP BY
S.Name, Peak.PeakUsage
P.S., next time around, you may want to tag with "SQL". There are relatively few Teradata people out there, but plenty who can help with basic SQL questions.

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

Oracle date / order by question

I want to select a date from oracle table formatted like select (to_char(req_date,'MM/YYYY')) but I also want to order the result set on this date format.
I want them to be ordered like dates not strings.
Like this
09/2009
10/2009
11/2009
12/2009
01/2010
02/2010
03/2010
04/2010
05/2010
06/2010
07/2010
08/2010
09/2010
10/2010
11/2010
12/2010
Not like
01/2010
02/2010
03/2010
04/2010
05/2010
06/2010
07/2010
08/2010
09/2009
09/2010
10/2009
10/2010
11/2009
11/2010
12/2009
12/2010
Any way to do this in sql?
Full SQL is:
SELECT (to_char(req_date,'MM/YYYY')) as monthYear, count(req_id) as count
FROM REQUISITION_CURRENT t
GROUP BY to_char(req_date,'MM/YYYY')
Thanks
Try this. It works and it's efficient, but looks a little messy.
select to_char(trunc(req_date, 'MM'),'MM/YYYY') as monthYear
,count(req_id) as count
from requisition_current
group
by trunc(req_date, 'MM')
order
by trunc(req_date, 'MM');
Try this
select monthyear,yr,month,count(req_id)
from
(
SELECT (to_char(req_date,'MM/YYYY')) as monthYear, to_char(req_date,'YYYY') yr, to_char(req_date,'mm') month, req_id
FROM REQUISITION_CURRENT t
) x
GROUP BY monthyear,yr,month
order by yr, month
Please try
Select req_date, (to_char(req_date,'MM/YYYY')) from MY_TABLE order by req_date
You are free to add additional sort fields, even if they are the same field.
Just use order by req_date instead of order by to_char(req_date,'MM/YYYY').
Try
SELECT ...
ORDER BY MIN(req_date)
That'll get around Oracle's rules about what can be selected after a GROUP BY.
I am considerably late to the party, but the most intuitive way I've found to achieve this is the following:
SELECT DISTINCT
to_char(req_date,'MM/YYYY') as monthYear,
count(req_id) as count
FROM
REQUISITION_CURRENT t
GROUP BY
to_char(req_date,'MM/YYYY')
ORDER BY
to_date(monthYear,'MM/YYYY')
It's may not the most computationally efficient method since it converts the date to a character and then back to a date, but that is precisely what you are asking a query like this to do. It also saves you from adding support columns or nesting subqueries.