SQL: Is there a way to use a new/user defined variable within the same SELECT statement? - proc-sql

I am curious if it is possible to use/reference a newly user created variable within the same SELECT statement. Below is some sample code of something I would try to do (calculate AGE and make an indicator variable for patients who are age >= 60) all within the same SELECT statement
create table AGE_60_UP as
select ID
, DATE_OF_BIRTH
, INDEX_DATE
, (year(INDEX_DATE) - year(DATE_OF_BIRTH)) as AGE
, case when AGE >= 60 then 1 else 0
end as AGE_60_UP_INDICATOR;
from MY_TABLE;
quit;
The error message I get is:
"ERROR: The following columns were not found in the contributing tables: AGE"
Thanks in advance for any help or tips!

You cannot use a computed column to compute another computed column in the same scope. However, you can use a subquery to compute the first column, and then use it in the external query for the second computed column.
For example, you can do:
create table AGE_60_UP as
select *,
case when AGE >= 60 then 1 else 0 end as AGE_60_UP_INDICATOR
from (
select
ID, DATE_OF_BIRTH, INDEX_DATE,
year(INDEX_DATE) - year(DATE_OF_BIRTH) as age
from my_table
) x

Related

Group by and calculation from value on the next row

I'm quite new to sql server. I can't seem to figure this out. I have a table that looks like this.
I need to be able to calculate the percentage change in the number for each name, for each year, in the column p. So the end result should look like this.
You can easily calculate the % difference using lag()
select name, date, number,
Cast(((number * 1.0) - Lag(number,1) over(partition by name order by date))/ Lag(number,1) over(partition by name order by date) * 100 as int)
from table

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

SQL EXTRACT(YEAR FROM MYDATE) not a GROUP BY expression

I have table MYTABLE with columns mydate and quantity of VARCHAR2 type.
|mydate| |quantity|
10/15/2010 15
01/20/2010 20
05/16/2005 30
04/29/2005 50
03/30/2008 5
I want to get:
|year| |quantity|
2010 35
2005 80
2008 5
I try:
SELECT
to_char(mydate,'yyyy') YEAR,
SUM(to_number(quantity))
FROM MYTABLE
GROUP BY
to_char(mydate,'yyyy');
But I get an error
ORA-00979: not a GROUP BY expression
What did I do wrong?
You must put all columns of the SELECT in the GROUP BY or use functions on them which compress the results to a single value (like MIN, MAX or SUM).
A simple example to understand why this happens: Imagine you have a database like this:
FOO BAR
0 A
0 B
and you run SELECT * FROM table GROUP BY foo. This means the database must return a single row as result with the first column 0 to fulfill the GROUP BY but there are now two values of bar to chose from. Which result would you expect - A or B? Or should the database return more than one row, violating the contract of GROUP BY?
Try this
select extract(year from mydate),sum(to_number(quant)) from mytable
group by extract(year from mydate);
SQLFiddle Example

Oracle sql count

I have below information in table and want to retrive the count if difference between two dates is >= 1.
Id testdate exdate
1 20120502 20120501 --> This should included, because diff is 1
2 20120601 20120601 --> This should not included, because diff is 0
3 20120704 20120703 --> This should included, because diff is 1
4 20120803 20120802 --> This should included, because diff is 1
Based on the above data, my select count should return 3.
I am trying the following, but it's not giving any results:
select count(to_char(testdate,'YYYYMMDD')-to_char(exdate,'YYYYMMDD')) from test ;
select count(*)
from my_table
where testdate <> exdate
You really should convert those to a date data-type though... it saves a lot of problems in the long run.
Your query will give you results. It will return 4. It gives you results because as long as the result of testdate - exdate is not null it will return a value for that row.
However, as you're not using dates Oracle will most probably convert those to numbers, which won't help for date comparisons should you do that in the future.
20120901 - 20120831 = 70 -- not 1
Okay, from your comment:
Working with ,if i use down voteaccept select count(*) from test where
to_char((testdate,'YYYYMMDD') - to_char(exdate,'YYYYMMDD')) >= 1; .But
count is one of the column.how to retrive above select statement as
one of the column
you're trying something completely different.
Your dates are actually dates; it's helpful to post this. You're looking for an analytic function, specifically count().
select a.*, count(*) over ( partition by 1 ) as ct
from my_table a
where trunc(exdate) <> trunc(testdate)
Note the trunc function, which, without additional parameters will remove the time portion of the date this enabling a direct comparison without resorting to converting the date to a character.
select count(*)
from test
where to_date(testdate,'YYYYMMDD') - to_date(exdate,'YYYYMMDD') >= 1;
or
select count(*)
from test
where to_date(testdate,'YYYYMMDD') <> to_date(exdate,'YYYYMMDD');
Looking at testdate and exdate it looks more like the columns are VARCHAR type so you would require apropriate date conversion.
In Oracle if the type is date you can calculate with them. 1 equal 1 day. 1/24 equals 1 hour.
Your case is rather easy because you could even compare the strings.
SELECT count(*)
FROM test
WHERE testdate <> exdate
But it sounds like you want to be able to be variable, so you rather convert them to a date and then you can do
SELECT count(*)
FROM test
WHERE to_date(testdate,'YYYYMMDD')-to_date(exdate,'YYYYMMDD') >= 1
I am not sure what you want if testdate minus exdate is -1 or more because the exdate is after testdate. Then you can work with ABS
SELECT count(*)
FROM test
WHERE ABS(to_date(testdate,'YYYYMMDD')-to_date(exdate,'YYYYMMDD')) >= 1

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