I need to add some custom values to a report and I am trying to add a column based on some logic. Is it possible to add a "cost" column based on the age range calculated from a date of birth column?
'Cost' AS (CASE WHEN TO_CHAR(SYSDATE,'yyyy')-TO_CHAR(DOB.BIRTHDATE,'yyyy') >= 0 AND TO_CHAR(SYSDATE,'yyyy')-TO_CHAR(DOB.BIRTHDATE,'yyyy') < 25) THEN 'Cost' = 0.05) END AS "Cost"
That would be
select
CASE WHEN to_number(TO_CHAR(SYSDATE,'yyyy')) - to_number(TO_CHAR(DOB.BIRTHDATE,'yyyy')) >= 0 AND
to_number(TO_CHAR(SYSDATE,'yyyy')) - to_number(TO_CHAR(DOB.BIRTHDATE,'yyyy')) < 25
THEN 0.05
END AS cost
from some table
You used wrong syntax, double quotes (where you shouldn't - that's not an error, but it's not needed either), subtracted characters.
Related
I have a bookings table that has a check_in and check_out columns in addition to deposit and balance columns. The check_in and check_out are date columns while deposit and balance is decimal column.
I want to generate a report for revenue that sums the deposit and balance columns for a given date interval (supplied from the UI). Here is what I have:
$deposit = Booking::whereRaw("check_in >= '$start'")
->whereRaw("check_out <= '$end'")
->sum('deposit');
$balance = Booking::whereRaw("check_in >= '$start'")
->whereRaw("check_out <= '$end'")
->sum('balance');
$revenue = $deposit + $balance;
I am however getting wrong figures. What am I doing wrong?
When you chain whereRaw you get the result for the records that have both, as AND. Maybe you want OR
Let's say we have this table
DB::table('checkout')->whereRaw("check_in >= 5")->whereRaw("check_out < 5")->sum("sum") gets you the result 0, since none of the records have check_out < 5 and check_in >= 5 at the same time.
DB::table('checkout')->whereRaw("check_in >= 5 OR check_out < 5")->sum("sum") gets you 10.
This should point you in the right way.
I have a column in my table in which I can insert M or F, according to the user's gender (Male or Female).
I need to generate this column randomly.
This column type is VARCHAR2(1).
I think I should use something like :
TRUNC(dbms_random.value(X,X))
But I dont know how.
Since dbms_random.value returns a value >= 0 and < 1, I'd just use something like this assuming you want an equal probability of getting an M or an F. If you want to produce a skewed distribution, adjust the 0.5 value to whatever you'd like
case when dbms_random.value < 0.5
then 'M'
else 'F'
end
I am trying to divide the data above, that is in the same column within my raw data. The one column name is "Status". I split it under this column into 2 separate columns within Tableau.
How would I create a calculation to divide T & D by each other? For an example, I would like to divide 166/1523, 155/1535, etc.
How do I differentiate between these 2 under the same column "Status".
SUM (IF [Status] = "T" THEN [Your Measure] END)
/
SUM (IF [Status] = "D" THEN [Your Measure] END)
I have a table with few columns including 2 varchar2(200) columns. In this columns we basically store serial numbers which can be numeric or alpha-numeric. Alpha-numeric values always both serials are same in those 2 columns. However for number serials it is a range like (first column value = 511368000004001226 and second column value = 511368000004001425 with 200 different (Qty)). Maximum length of the serial is 20 digits. I have indexed both the columns.
Now I want to sear a serial in-between the above range. (lets say 511368000004001227). I use following query.
SELECT *
FROM Table_Namr d
WHERE d.FROM_SN <= '511368000004001227'
AND d.TO_SN >= '511368000004001227'
Is it a valid query? Can I use <=> operators for numbers in a varchar column?
Yes, You can use >= and <= operators on Varchar2 columns but it will behave like it is string and comparison between strings will take place.
In this case, 4 will be considered greater than 34 means '4' > '34' but number 4 is less than 34.
It is not a good practice to store a number in Varchar2. You will lose the functionality of Numbers if you store them in varchar2.
You can check the above concept using following:
select * from dual where '4' > '34'; -- gives result 'X'
select * from dual where 4 > 34; -- Gives no result
You can try to convert the varchar2 column to number using to_number if possible in your case.
Cheers!!
Your Query is "valid" in the sense, that it works, and will deliver a result. If you are looking from a numeric standpoint, it will not work correctly, as the range operators for VARCHAR columns work the same way, as it would sort an alphanumeric value.
e.g.
d.FROM_SN >= '51000'
AND d.TO_SN <= '52000'
This would match for values, as you would expect, like 51001, 51700, but would also deliver unexpected values like 52, or 5100000000000000
If you want numeric selection, you would need to parse it - which of course only works, if every value in these columns is numeric:
TO_NUMBER(d.FROM_SN) >= 51000
AND TO_NUMBER(d.TO_SN) <= 52000
You may use alphanumerical comparison provided
1) your ranges are of the same length and
2) all the keys in the range are of the same length
Example data
SERNO
----------------------------------------
101
1011
1012
1013
1014
102
103
104
This doesn't work
select * from tab
where serno >= '101' and serno <= '102';
SERNO
----------------------------------------
101
102
1011
1012
1013
1014
But constraining the lentgh of the result provides the right answer
select * from tab
where serno >= '101' and serno <= '102'
and length(serno) = 3;
SERNO
----------------------------------------
101
102
My tables are as below
MS_ISM_ISSUE
ISSUE_ID ISSUE_DUE_DATE ISSUE_SOURCE_TYPE
I1 25-11-2018 1
I2 25-12-2018 1
I3 27-03-2019 2
MS_ISM_SOURCE_SETUP
SOURCE_ID MODULE_NAME
1 IT-Compliance
2 Risk Assessment
I have written following query.
with rs as
(select
count(ISSUE_ID) as ISSUE_COUNT, src.MODULE_NAME,
case
when ISSUE_DUE_DATE<sysdate then 'Overdue'
when ISSUE_DUE_DATE between sysdate and sysdate + 90 then 'Within 3 months'
when ISSUE_DUE_DATE>sysdate+90 then 'Beyond 90 days'
end as date_range
from MS_ISM_ISSUE issue, MS_ISM_SOURCE_SETUP src
where issue.Issue_source_type = src.source_id
group by src.MODULE_NAME, case
when ISSUE_DUE_DATE<sysdate then 'Overdue'
when ISSUE_DUE_DATE between sysdate and sysdate + 90 then 'Within 3 months'
when ISSUE_DUE_DATE>sysdate+90 then 'Beyond 90 days'
end)
select ISSUE_COUNT,MODULE_NAME, DATE_RANGE,
(select count(ISSUE_COUNT) from rs where rs.MODULE_NAME=MODULE_NAME) as total from rs;
The output of the code is as below.
ISSUE_COUNT MODULE_NAME DATE_RANGE Total
1 IT-Compliance Overdue 3
1 IT-Compliance Within 3 months 3
1 Risk Assessment Beyond 90 days 3
The result is correct till 3rd column. In 4th column what I want is, total of Issue count for given module name. Hence in above case Total column will have value as 2 for first and second row (since there are 2 Issues for IT-Compliance) and value 1 for the third row (since one issue is present for Risk Assessment).
Essentially, I want to achieve is to replace current row's MODULE_NAME in last where clause. How do I achieve this using query?
OK, this condition
where rs.MODULE_NAME=MODULE_NAME
is essentially the same as if you wrote
where MODULE_NAME = MODULE_NAME
which is simply always true (if there are no nulls in module_name).
Try using different table alias for inner query and outer query, e.g.
select count(ISSUE_COUNT) from rs rs2 where rs2.MODULE_NAME=rs.MODULE_NAME
You can also try to use analytic function here, something like
select ISSUE_COUNT,
MODULE_NAME,
DATE_RANGE,
COUNT(ISSUE_COUNT) OVER (PARTITION BY RS.MODULE_NAME) AS TOTAL
from rs
instead of your subquery