Select only a set to improve perfomance - jpa

I search to know if a user have an active subscription
#Query("select case when count(u) > 0 then true else false end from User u where u.id=:userId and current_date < u.subscriptionEndDate")
boolean userActiveSubscription(Long userId);
subscriptionEndDate use a localdate
Probably user object is queried, is there a way to limit data retrived to return true or false
Generated query
select
case
when count(user0_.id)>0 then 1
else 0
end as col_0_0_
from
user user0_
where
user0_.id=?
and current_date<=user0_.subscription_end_date

Related

Postgresql count from multiple columns in a row

I have this table on a postgres db (proofs). proof_1, proof_2 and proof_3 are boolean columns indicating whether the user (user_id) has submitted the proofs:
user_id
proof_1
proof_2
proof_3
1
true
true
false
2
true
false
false
3
true
true
true
I need to count how many proofs are submitted by each user. This is the query that I came up:
> select
user_id,
length(
concat(
case when proof_1 then '1' end,
case when proof_2 then '1' end,
case when proof_3 then '1' end)
)) as proof_counts
from
proofs
The query above would work. But I don't think that it is the best query to do. Please advice on what query should be done?
select user_id,
case when proof_1 then 1 else 0 end
+ case when proof_2 then 1 else 0 end
+ case when proof_3 then 1 else 0 end as proof_counts
from (
values (1,true,true,false), (2,false,true,false)
) as proof (user_id, proof_1, proof_2, proof_3)
If there is no null values then below query
select user_id,
proof_1::integer
+ proof_2::integer
+ proof_3::integer as proof_counts
from (
values (1,true,true,false), (2,false,true,false)
) as proof (user_id, proof_1, proof_2, proof_3)
And version which handle nulls
select user_id,
coalesce(proof_1::integer,0)
+ coalesce(proof_2::integer,0)
+ coalesce(proof_3::integer,0) as proof_counts
from (
values (1,null,true,false), (2,false,true,false)
) as proof (user_id, proof_1, proof_2, proof_3)
I think this is also a good alternative:
select user_id,
sum(case when proof_1 = true then 1 else 0 end) + sum(case when proof_2 = true then 1 else 0 end) + sum(case when proof_3 = true then 1 else 0 end) as proof_counts
from proofs
group by user_id
This is possible just by converting your boolean to integer and then summing the three columns
Query:
select
userid_id,
sum(case when proof_1=true then 1 end)+sum(case when proof_2=true then 1 end)+sum(case when proof_2=true then 1 end) as total_proofs_submitted
from proofs
group by user_id

How to perform Grouping equivalent like Informatica?

I've an Informatica function which I want to convert into query to be getting used in Spring Batch code.
I've a table EMPLOYEE table having 15 fields (all I want in select) and Informatica has function Router which creates group based on STATUS_CD = 'A' and default (means all other records should go here - where status is other than A).
How can we do in Postgres?
I've all the employees and I want to check based using combination of EMPLOYEE_CD, EMPLOYEE_ID is unique and I want to simply return the count of it.
Query1
SELECT EMPLOYEE_CD AS EMPLOYEE_CD,
EMPLOYEE_ID AS EMPLOYEE_ID,
COUNT (*) AS CNT
FROM EMPLOYEE
GROUP BY EMPLOYEE_CD, EMPLOYEE_ID
HAVING COUNT (*) > 1;
Query 2
SELECT EMPLOYEE_ID, EMPLOYEE_NAME, EMPLOYEE_EMAIL, EMPLOYEE_PHONE, EMPLOYEE_ADDRESS, (Create Count Field here)
FROM EMPLOYEE
Query 3 - I need to group (which is my original question) or Create Columns ACTIVE, NON_ACTIVE columns as a part of query results where EMPLOYEE_STAT_CD = 'A', ACTIVE column value should say YES and EMPLOYEE_STAT_CD other than A, NON_ACTIVE should say Yes.
How can merge Query1 and Query 2 and Query 3 into single query ?
if I understood the question, your code is something like:
SELECT EMPLOYEE_ID, EMPLOYEE_NAME, EMPLOYEE_EMAIL, EMPLOYEE_PHONE, EMPLOYEE_ADDRESS,
COUNT(*)OVER(PARTITION BY EMPLOYEE_CD, EMPLOYEE_ID) AS counter_from_sql1,
CASE WHEN EMPLOYEE_STAT_CD = 'A' THEN 'YES' ELSE NULL END AS ACTIVE,
CASE WHEN EMPLOYEE_STAT_CD <> 'A' THEN 'YES' ELSE NULL END AS NON_ACTIVE
FROM EMPLOYEE;
or
SELECT * FROM (
SELECT EMPLOYEE_ID, EMPLOYEE_NAME, EMPLOYEE_EMAIL, EMPLOYEE_PHONE, EMPLOYEE_ADDRESS,
COUNT(*)OVER(PARTITION BY EMPLOYEE_CD, EMPLOYEE_ID) AS counter_from_sql1,
CASE WHEN EMPLOYEE_STAT_CD = 'A' THEN 'YES' ELSE NULL END AS ACTIVE,
CASE WHEN EMPLOYEE_STAT_CD <> 'A' THEN 'YES' ELSE NULL END AS NON_ACTIVE
FROM EMPLOYEE
) z
WHERE counter_from_sql1 > 1;

Need help rewriting a T-SQL query for results to get displayed in a stacked bar

I have come up with the following query which gives rise to the below result.
SELECT TOP (100) PERCENT s.UserfName AS ASSIGNEE, e.status, COUNT(*) AS [TOTAL COUNT], CASE WHEN e.status = "Open" THEN 'OPEN' END AS
FROM dbo.t_helpdesktickets AS e INNER JOIN
dbo.t_assetusers AS s ON e.currentlyat = s.UserID
WHERE (e.status IN ('open', 'closed'))
GROUP BY s.UserfName, e.status
How will I rewrite my query to return results as below
Use conditional aggregation:
SELECT
s.UserfName AS ASSIGNEE,
COUNT(CASE WHEN e.status = 'open' THEN 1 END) AS "OPEN",
COUNT(CASE WHEN e.status = 'closed' THEN 1 END) AS "CLOSED"
FROM dbo.t_assetusers AS s
LEFT JOIN dbo.t_helpdesktickets AS e
ON e.currentlyat = s.UserID
GROUP BY
s.UserfName;
Note that I switched to using a left join here, in case certain users might not have any records corresponding to either of the two statuses. Using this approach, the open/closed counts would then show up as zero.

Postgres optimize SELECT and indexes

I have written a query to summarise financial transactions so that I can go back to any date and find out what the financial position was at that time.
The data is multi company so the data holds information for all the group companies
Being financial information, some of the accounts reset themselves at each year end whilst others have a running balance.
The structure of the tables is:
nominal_account - Return 1 row for each account
nominal-transaction_lines - the full dataset
nominal_period_year - is a summary of transactions that is based on the nominal account, month/year and the financial company.
My SQL below works but takes over a minute to generate (the SQL below is based on today's date).
The query is broken into a few sections.
The first part of the case (na1.id=178) is a special account that is the summary of all income/expenditure records for that financial year.
The second part first looks for any records in the summary table until the last month end and then goes to the transaction table to find any records since the beginning of the current month. Added together that makes the balance.
At present the transaction table has around 25m records and the summary table 26000.
I am not asking for the query to be written for me, just some hints as to how to speed it up. So if anyone could suggest ways to optimize it or which indexes would help to speed it up, I would be very grateful.
SELECT id, nominal_code AS nom_code, description AS descr, COALESCE(management_type,0) AS type,
case
when na1.id = 178
then (SELECT coalesce( (SELECT sum(period_movement)
FROM nominal_period_year JOIN nominal_account on nominal_account.id = nominal_period_year.nominal_account
WHERE (period_key/10000000000) <= 201704 AND
financial_company = 1 AND
nominal_account.profit_or_balance = true)
+
(SELECT sum(period_movement) FROM nominal_period_year WHERE nominal_account = na1.id AND
(period_key/10000000000) <= 201803 AND nominal_period_year.financial_company = 1)
+
(SELECT GREATEST(0, sum(db_Amount)) - GREATEST(0, sum(cr_Amount))
FROM nominal_transaction_lines
WHERE transaction_date between '2018-04-01' AND '2018-04-27'
AND original_id = 0
AND reversed_by = 0
AND status = 'A'
AND financial_company = 1 AND status = 'A' AND nominal_account = na1.id)
,0.00) AS balance)
ELSE
(SELECT coalesce(
(SELECT sum(period_movement) FROM nominal_period_year WHERE nominal_account = na1.id AND
(case
when na1.profit_or_balance = true
then (period_key/10000000000) > 201704
ELSE period_key > 0
end)
AND (period_key/10000000000) <= 201803 AND nominal_period_year.financial_company = 1)
+
(SELECT GREATEST(0, sum(db_Amount)) - GREATEST(0, sum(cr_Amount))
FROM nominal_transaction_lines
WHERE transaction_date between '2018-04-01' AND '2018-04-27'
AND original_id = 0
AND reversed_by = 0
AND financial_company = 1
AND status = 'A'
AND nominal_account = na1.id)
,0) AS balance)
end
FROM nominal_account AS na1
order by nom_code;

how to select only those brands which don't have status = true in any of the products

Query is
select brand
from products
where status = false
and brand not in (
select brand
from products
where status = true
group by brand
)
group by brand;
Basically, i want to select only those brands which don't have status = true in any of the products.
I want to optimize the above query
Use the boolean aggregate function bool_or():
select brand
from products
group by brand
having not bool_or(status);
You can convert the boolean values to bit using a CASE statement, then MAX on that:
SELECT brand
FROM products
GROUP BY brand
HAVING MAX(CASE WHEN status = TRUE THEN 1 ELSE 0 END) = 1