Combining an IF statement with current query - mysql

I've got the following query that's finding all subscribers between a certain date:
SELECT s.id as 'Subscription ID', s.customer_id as 'Customer ID', s.start_date as 'Start Date', s.status as 'Current Status', l.date 'Cancellation Date'
FROM subscriptions as s
LEFT JOIN subscriptionlog as l ON s.id=l.subscription_id
WHERE s.start_date >= 1559347200
AND s.start_date <= 1596239999
I've added the last column "Cancellation date" where I want to find the following:
l.event = 'subscription_cancelled'
If that exists for a subscriber can it output l.date but if it can't find it, can the column be left blank for that line? How can I incorporate an IF statement?

This looks like a job for CASE clause. You can put it in your select clause for if-else display issues. You can also put it in your WHERE clause for a more robust filter.
In your case:
SELECT
s.id as 'Subscription ID',
s.customer_id as 'Customer ID',
s.start_date as 'Start Date',
s.status as 'Current Status',
CASE
WHEN l.event = 'subscription_cancelled'
THEN l.date
ELSE NULL
END as 'Cancellation Date'
FROM subscriptions as s
LEFT JOIN subscriptionlog as l ON s.id=l.subscription_id
WHERE s.start_date >= 1559347200
AND s.start_date <= 1596239999

Related

#1054 - Unknown column in 'on clause' whereas alias defined

here's my query which gives the error "#1054 - Unknown column 'request1.orgname' in 'on clause'":
SELECT request.orgname,
request1.API_name AS 'API name',
SUM(CASE WHEN request.username IS NULL
THEN request.projects_priced_count
else 0
END) AS 'API prices calls',
SUM(request.projects_priced_count) AS 'Total prices calls'
FROM prod_virida_pricing.request
LEFT OUTER JOIN (
SELECT api_key.name AS 'API_name',
api_key.orgname AS 'Organization',
date(expiry_date) AS 'API expiry date',
is_active AS 'Active org'
FROM prod_virida_auth.api_key
INNER JOIN prod_virida_auth.organization ON api_key.orgname = organization.orgname
WHERE api_key.blocked = 0
AND organization.is_active = 1) request1 ON request.orgname = request1.orgname
ORDER BY orgname
;
This will solve the problem
Better to use aliases(table1 & table2 in the e.g.) for different subqueries to reduce confusion for SQL to understand to understand the correct columns.
SELECT request.orgname AS 'Organization',
request1.API_name AS 'API name',
SUM(CASE WHEN request.username IS NULL
THEN request.projects_priced_count
else 0
END) AS 'API prices calls',
SUM(request.projects_priced_count) AS 'Total prices calls'
FROM prod_virida_pricing.request AS table1
LEFT OUTER JOIN (
SELECT api_key.name AS 'API_name',
api_key.orgname AS 'Organization',
date(expiry_date) AS 'API expiry date',
is_active AS 'Active org'
FROM prod_virida_auth.api_key
INNER JOIN prod_virida_auth.organization ON api_key.orgname = organization.orgname
WHERE api_key.blocked = 0
AND organization.is_active = 1) AS table2 ON table1.Organization= table2.Organization
ORDER BY table1.Organization
;

Converting a MySQL script to PostgreSQL results in "ERROR: schema does not exist" error

I have this query in MySQL that lists all Moodle courses that have been accessed in the last 2 years and the user (+ their Moodle role) that last accessed it. I'm trying to convert it to PostgreSQL 9.3.22 so it can run on another Moodle LMS I administrate. However, the query fails with the error ERROR: schema "cat" does not exist.
MySQL query:
select cat.id 'category id',
cat.name 'category',
lsl.courseid,
c.fullname 'course fullname',
case when c.visible = '1'
then 'yes'
else 'no'
end as "course visibility",
from_unixtime(max(lsl.timecreated), '%H:%i %D %M %Y') 'lastaccessed',
lsl.userid 'lastaccesseduserid',
u.username 'last accessed by',
case when r.shortname is null
then 'user is not enrolled in this course'
else r.shortname
end 'role'
from prefix_logstore_standard_log lsl
join prefix_course c on c.id = lsl.courseid
join prefix_course_categories cat on cat.id = c.category
join prefix_user u on u.id = lsl.userid
left join prefix_role_assignments ra on ra.contextid = lsl.contextid -- left join in case the last accessed user wasn't enrolled in the course (i.e. admin staff).
left join prefix_role r on r.id = ra.roleid
group by lsl.courseid
having max(lsl.timecreated) > unix_timestamp(date_sub(now(), interval 24 month))
order by lsl.courseid asc
My PostgreSQL conversion attempt:
select cat.id 'category id',
cat.name 'category',
lsl.courseid,
c.fullname 'course fullname',
case when c.visible = '1'
then 'yes'
else 'no'
end as "course visibility",
to_char(to_timestamp(max(lsl.timecreated)), 'HH24:MI DD/MM/YYYY') "last accessed date",
lsl.userid 'lastaccesseduserid',
u.username 'last accessed by',
case when r.shortname is null
then 'user is not enrolled in this course'
else r.shortname
end "role"
from prefix_logstore_standard_log lsl
join prefix_course c on c.id = lsl.courseid
join prefix_course_categories cat on cat.id = c.category
join prefix_user u on u.id = lsl.userid
left join prefix_role_assignments ra on ra.contextid = lsl.contextid -- left join in case the last accessed user wasn't enrolled in the course (i.e. admin staff).
left join prefix_role r on r.id = ra.roleid
group by lsl.courseid
having max(lsl.timecreated) > extract(epoch from now()- interval '2 year')
order by lsl.courseid asc
I checked the database's schema, and the table exists, but I don't understand why this error occurs on the prefix_course_categories table only. I don't know PostgreSQL very well, so your assistance is greatly appreciated!

SQL Server 2014 excluding rows

My query:
`SELECT gft_key,
DonorCustomer.cst_ind_full_name_dn as 'Full Name',
DonorCustomer.cst_ixo_title_dn as 'Job Title',
DonorCustomer.cst_org_name_dn as 'Organization',
DonorCustomer.cst_eml_address_dn as 'Email Address',
apl_code as 'Appeal Code',
cmp_code as 'Campaign Code',
prd_name as 'Product Name',
chp_name as 'Chapter Name',
adr_line1,
adr_line2,
adr_city as 'City',
adr_post_code as 'Zip Code',
adr_country as 'Country',
mem_member_type as 'Member Type',
ivd_amount_cp as 'Gift Amount',
fun_code as 'Purpose Code',
gty_type as 'Gift Type',
gft_date as 'Gift Date',
pay_trx_date,
case
when pay_trx_date is null then 'Not Paid' else 'Paid' end as 'Paid?'
FROM
np_gift
JOIN np_gift_type ON gft_gty_key=gty_key
JOIN np_constituent ON gft_dnr_cst_key=dnr_cst_key
JOIN co_customer DonorCustomer ON dnr_cst_key=DonorCustomer.cst_key
JOIN co_customer_x_address ON cst_cxa_key = cxa_key
JOIN co_address ON cxa_adr_key = adr_key
JOIN oe_product ON gft_fpc_prd_key=prd_key
LEFT JOIN np_purpose ON gft_fun_key=fun_key
LEFT JOIN np_campaign ON gft_cmp_key=cmp_key
LEFT JOIN np_appeal ON gft_apl_key=apl_key
JOIN ac_invoice_detail ON gft_ivd_key=ivd_key and ivd_void_flag=0
left outer join ac_payment_detail on pyd_ivd_key=ivd_key
left outer join ac_payment on pyd_pay_key=pay_key
left outer join ac_payment_info on pay_pin_key=pin_key
LEFT JOIN vw_client_uli_member_type ON dnr_cst_key=mem_cst_key
LEFT JOIN co_customer_x_customer ON cxc_cst_key_1 = DonorCustomer.cst_key and (cxc_end_date is null or datediff(dd,getdate(),cxc_end_date) >=0) and cxc_rlt_code='Chapter Member'
LEFT JOIN co_chapter ON cxc_cst_key_2=chp_cst_key
where (pay_trx_date >= '7/1/2017' or pay_trx_date is null)
order by gft_date`
Sample data that I get by running the query: Gift Date pay_trx_date
2013-11-18 2017-07-12
2013-11-29 NULL
2014-12-15 NULL
2017-06-30 NULL
2015-05-01 2017-07-01
By running the query above I accomplish the above result set. However, I want to exclude rows where the gift date is < '7/1/2017' and pay_trx_date is NULL (Just like the middle rows in my sample data) at the same time though I want to keep rows where the gift date is <= '7/1/2017' and pay_trx_date is not NULL (Just like the first or last row in my sample data)
You can use your current query as inner block and filter one time as per your requirement.
SELECT * FROM (
-- Your Current Query
) Q
WHERE gft_date <= '7/1/2017' AND pay_trx_date IS NOT NULL

Moodle SQL - Creating Filter with 2 user profile fields data

New to this moodle sql using configurable reports plugin.
SELECT u.username AS 'User name',
u.firstname AS 'First name',
u.lastname AS 'Last Name',
c.fullname AS 'Course',
u.department AS 'department',
DATE_FORMAT(FROM_UNIXTIME(p.timeenrolled),'%m/%d/%Y') AS 'Enrollment Date',
DATE_FORMAT(FROM_UNIXTIME(p.timecompleted),'%m/%d/%Y') AS 'Completion Date',
DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(p.timecompleted),INTERVAL 1 YEAR), '%Y-%m-%d') AS 'Expiration Date'
FROM prefix_course_completions AS p
JOIN prefix_course AS c ON p.course = c.id
JOIN prefix_user AS u ON p.userid = u.id
WHERE 1 = 1
%%FILTER_SUBCATEGORIES:cc.path%%
%%FILTER_COURSES:Course%%
%%FILTER_USERS:Department%%
%%FILTER_SEARCHTEXT:u.firstname:~ %%
ORDER BY u.firstname
Is there a way where I can Filter the search text using first name and last name?
Like: %%FILTER_SEARCHTEXT:u.firstname:~ + u.lastname:~ %% or should I CONCAT them to make this work? Haven't found anything about this in moodle community and configurable reports documentation.
CONCAT works for me ;)
%%FILTER_SEARCHTEXT:CONCAT (u.firstname, ' ',u.lastname):~%%

Display the list of people who is not present today from mysql query

I am trying to display the list of people who have
Case 1:
Forgotton to check-in and are present
Case 2:
Who are absent today and can't check-in today.
In both cases,check-in will be null because both have not checked-in
This is what I have achieved so far
SELECT
u.id,
u.`firstname` AS 'Firstname',
u.`lastname` AS 'Lastname',
ulr.leave_status AS 'Leave Status',
ulr.leave_from AS 'Leave From',
ulr.leave_to AS 'Leave To',
ulr.leave_description AS 'Leave Description',
DATE_FORMAT(
ulr.leave_from,
'%Y-%m-%d'
) AS 'Today''s Date'
FROM
users u
INNER JOIN users_leave_request ulr ON u.id = ulr.user_id
INNER JOIN checkin_checkout cc ON u.id = cc.users_id
WHERE
DATE_FORMAT(
leave_from,
'%Y-%m-%d'
) = CURDATE()
AND cc.checkin_time IS NULL
users_leave_request table: table1
checkin_checkout table: table2
This query will select all users that didn't checkin for today and if they had record in users_leave_request the data for that records will also be returned.
By using LEFT JOIN we avoid returning empty result for not checked-in user who don't have entry in users_leave_request. If we use JOIN, result will be returned only if records are found in both users and users_leave_request tables.
SELECT
u.id,
u.`firstname` AS 'Firstname',
u.`lastname` AS 'Lastname',
ulr.leave_status AS 'Leave Status',
ulr.leave_from AS 'Leave From',
ulr.leave_to AS 'Leave To',
ulr.leave_description AS 'Leave Description',
DATE_FORMAT(
ulr.leave_from,
'%Y-%m-%d'
) AS 'Today''s Date'
FROM users AS u
LEFT JOIN users_leave_request ulr ON u.id = ulr.user_id
WHERE u.id NOT IN (
SELECT u.id
FROM
users u
INNER JOIN checkin_checkout cc ON u.id = cc.users_id
WHERE
DATE_FORMAT(cc.checkin_time, '%Y-%m-%d') = CURDATE()
)