Get Day from array of days [duplicate] - tsql

This question already has answers here:
Referring to a Column Alias in a WHERE Clause
(9 answers)
Closed 3 years ago.
I am trying to capture a specific day of the week in a long list of dates (TxnDate). The below command I am using is throwing the following error:
Invalid column name 'TxnDay'.
Code
Select DATENAME(dw, ft.[TxnDate]) as TxnDay, ft.[ProductCode], ft.[Site] from dbo.FactTransactions as Ft
Where ft.[Site] = '1' and TxnDay = 'Tuesday'
EDIT: I have also tried the below with the following error:
Invalid column name 'TxnDay'.
Select ft.[TxnDate], ft.[ProductCode], ft.[Site] from
dbo.FactTransactions as Ft
Where ft.[Site] = '1' and ft.[TxnDate] in (SELECT DATENAME(dw, ft.
[TxnDate]) as TxnDay where TxnDay = 'Sunday')

Unless I'm missing something, I'm not sure you need the subquery in your WHERE clause at all - can't you just do:
select
ft.[TxnDate],
ft.[ProductCode],
ft.[Site]
from dbo.FactTransactions as ft
Where
ft.[Site] = '1'
and DATENAME(dw, ft.[TxnDate]) = 'Sunday'

Hi Don't use column's alias name in where clause.Solution is below.
Select DATENAME(dw, ft.[TxnDate]) as TxnDay, ft.[ProductCode], ft.[Site] from
dbo.FactTransactions as Ft
Where ft.[Site] = '1' and DATENAME(dw, ft.[TxnDate])= 'Tuesday'

Related

Passing Bind Variable in case statements in Oracle query

I want to pass Bind Variable (a Date) in a Case statement in order to achieve the following:
When User inputs a date and if that Date is falling on Monday, then the Case statement should fetch the value of Friday (meaning it should bypass the weekends and look for the values of a previous working day)
I tried to use the following query which works well when I use 'sysdate'
Select * from table_name
Where tradedate = trunc (sysdate - case to_char(sysdate, 'Dy')
when 'Mon' then 3 else 1 end);
but when I replace 'sysdate' with a Bind Variables, it gives me an error like:
tradedate = trunc (:sysdate1 - case to_char(:sysdate2, 'Dy')
when 'Mon' then 3 else 1 end);
ORA-00932: inconsistent datatypes: expected DATE got NUMBER
00932. 00000 - "inconsistent datatypes: expected %s got %s"
Can't we use Bind Variables in Case statement in oracle queries? If so, Can someone please give me any alternate solution to my problem stated above?
Any help would be really appreciated.
Below is the complete code:
select * from (
SELECT
S."TRADEDATE",S."ACCOUNT_NAME",S."BOOKING_AMOUNT",S."ACCOUNT_NUMBER",(CASE WHEN BOOKING_AMOUNT <0 THEN S."CREDIT" ELSE S."DEBIT" END) AS "DEBIT" , (CASE WHEN BOOKING_AMOUNT <0 THEN S."DEBIT" ELSE S."CREDIT" END) AS "CREDIT",
U.VALUE_DT , U.AC_NO , NVL(U.BOOKED_AMOUNT ,0) BOOKED_AMOUNT
FROM
SXB S
FULL OUTER JOIN UBS U ON
S.ACCOUNT_NUMBER = U.AC_NO
AND
S.TRADEDATE = U.VALUE_DT
UNION ALL
SELECT
BOOKING_DATE TRADEDATE,
'SAXO RECON' ACCOUNT_NAME,
SUM((Case when DR_CR_INDICATOR = 'D' then AMOUNT*-1 when DR_CR_INDICATOR = 'C' then AMOUNT end)) BOOKING_AMOUNT,
EXTERNAL_ACCOUNT ACCOUNT_NUMBER,
'Matched - ' ||A.MATCH_INDICATOR AS DEBIT,
NULL AS CREDIT,
VALUE_DATE VALUE_DT,
NULL AS AC_NO,
0 AS BOOKED_AMOUNT
FROM
FCUBS.RETB_EXTERNAL_ENTRY A
WHERE A.EXTERNAL_ENTITY = 'SAXODKKKXXX'
AND A.EXTERNAL_ACCOUNT = '78600/COMMEUR'
group by
BOOKING_DATE ,
EXTERNAL_ACCOUNT ,
VALUE_DATE,
MATCH_INDICATOR
order by tradedate, account_name)
where tradedate = trunc (:sysdate1 - case to_char(:sysdate2, 'Dy') when 'Mon' then 3 else 1 end);
SYSDATE is a date datatype so oracle will always treat it as a DATE datatype. For a bind variable I'd do an explicit conversion using TO_DATE(:bind_var, 'FORMAT_MASK'). For example:
select
case TO_CHAR(TO_DATE(:sysdate2,'DD-MON-YYYY'), 'Dy') when 'Mon'
then 3
else 1
end from dual

DATE_FORMAT in Postgresql? [duplicate]

This question already has answers here:
DATE_FORMAT in postgresql
(4 answers)
Closed last year.
I have this query using MySQL I need to convert it to PostgreSQL query
SELECT
count(*) AS aggregate
FROM
"contracts"
WHERE
DATE_FORMAT(created_at, '%Y-%c') = '2022-1'
I got this error:
Query 1 ERROR: ERROR: function date_format(timestamp without time zone, unknown) does not exist
LINE 6: DATE_FORMAT(created_at, '%Y-%c') = '2022-1'
You could use TO_CHAR to format the date or timestamp.
SELECT count(*) AS aggregate
FROM contracts
WHERE TO_CHAR(created_at, 'yyyy-mm') = '2022-01'
Or use a sargable alternative
SELECT count(*) AS aggregate
FROM contracts
WHERE created_at >= '2022-01-01'
AND created_at < '2022-02-01'

Count a specific value for many columns

I want to get an output that gives me the count of '0's of each column. For one column I get it by
select COUNT(*) from Q_Basis
where V1 = '0'
where the names of the relevant columns are v1, v2, ..., v60.
I have found out that I can do counts over all columns with
select count(*), *
but that does not help in my case since I still have to specify all columnnames in the where clause.
Any idea how I can acomplish this without hardcoding this in the where clause?
One way is to use conditional aggregation:
SELECT COUNT(CASE WHEN V1 = '0' THEN 1 END) As NumOfV1Zeros,
COUNT(CASE WHEN V2 = '0' THEN 1 END) As NumOfV2Zeros,
COUNT(CASE WHEN V3 = '0' THEN 1 END) As NumOfV3Zeros
FROM Q_Basis
WHERE '0' IN(V1, V2, V3) -- Don't count records that doesn't interest you...
You can't avoid specifying the column names individually, but if there are a lot of columns, you can dynamically create such a select statement using infromation_schema.columns.

Count entities by date that fall between start date and end date (postgres)

Using Postgres, I'm trying to get a count of active entities by day over the past year.
For each entity I have a name, a start date, an end date. Assume the schema below-
Table x
Entity|Start_date|End_date
x | 2018-01-07 |2018-01-23
y | 2018-01-08 |2018-04-01
z | 2018-01-22 |2018-01-24
What I'm trying to output
Date|Count
2018-01-01|0
...
2018-01-07|1
...
2018-01-22|3
2018-01-23|3
2018-01-24|2
2018-01-25|1
...
2018-08-15|0
Have created a date table but don't know what to join it on. Feel like I have to create another table, then aggregate it but not sure what it is. If I don't need to create an additional table then great.
Any help would be appreciated! T
edit - FWIW I've researched but I'm not quite sure what it is I need to research here - what function or join I'm missing
edit 2 - to include example
You can do that with a left joining year's dates and entities like:
select t.d, count(e.entity)
from generate_series(
make_date(date_part('year',current_date)::integer,1,1),
make_date(date_part('year',current_date)::integer,12,31),
'1 day'::interval) t(d)
left join entities e
on t.d between e.start_date and e.end_date
group by t.d
order by t.d;
well, you need count days for every Start_date and End_date from "x" table. (this happens in left join subquery).
Then you need just create all year days list and "left join" those all day to counted days from "x" table.
Hope, this is what you want and if so, also hope, do you understand, what I tried to explain.
WITH year_days as (
select * from generate_series('2018-01-01'::date, '2018-12-31'::date, '1 day'::interval) as d
),
x(Entity, Start_date, End_date) AS (
values
('x','2018-01-07'::date, '2018-01-23'::date),
('y','2018-01-08'::date, '2018-04-01'::date),
('z','2018-01-22'::date, '2018-01-24'::date)
)
select year_days.d, coalesce(t.cnt, 0) from year_days
left join (
select generate_series(Start_date, End_date, '1 day'::interval) as d , count(*) as cnt from x group by d
) t
on year_days.d = t.d

sorting DDMMYYYY monthly using postgreSQL

I am writing a query using PostgreSQL to count something but I want to sort the date (DDMMYYYY) properly.
With this following codes,
WITH dis_id AS (SELECT
DISTINCT ON (source_user_id) source_user_id,
created_at
FROM public.info_scammers )
SELECT d.date, count(dis_id.source_user_id)
FROM (SELECT to_char(date_trunc('day',(current_date - offs)), 'DD-MM-YYYY') AS date
FROM generate_series(0,365,1) AS offs
) d LEFT OUTER JOIN
dis_id
ON (d.date = to_char(date_trunc('day',dis_id.created_at),'YYYY-MM-DD'))
GROUP BY d.date
The result is
Date | Count
01-01-2017 | 0
01-02-2017 | 0
01-03-2017 | 0
What I want is
Date | Count
01-01-2017 | 0
02-01-2017 | 0
03-01-2017 | 0
I have looked up the existing problems. But most of them do not use PostgreSQL
Thank you
Leave d.date as type date in the inner SELECT (don't convert it to text with to_char), then add ORDER BY d.date and do the conversion to text in the outer SELECT.
Something like:
WITH dis_id AS (...)
SELECT to_char(d.date, 'DD-MM-YYYY'), count(...)
FROM (SELECT date_trunc(...) AS date
FROM ...
) d
LEFT OUTER JOIN ...
GROUP BY to_char(d.date, 'DD-MM-YYYY')
ORDER BY d.date;