I have 3 tables: accounts, transactions, statements. Account hasMany transactions & statements (foreign key is account_id).
I need to retrieve the account_name, balance of billed transactions, total & count of unbilled (pending) transactions and last statement-date for all accounts with either and outstanding balance and/or unbilled transactions.
This query returns the data as expected:
SELECT
Account.id, Account.account_name,
Billed.balance, Pending.items,
Pending.amount, Stmnt.latest
FROM
accounts as Account
LEFT JOIN
(SELECT
account_id,
(SUM(`Transaction`.`debit`) - SUM(`Transaction`.`credit`)) as balance
FROM
`transactions` AS `Transaction`
WHERE
`Transaction`.`statement_id` > 0 AND
`Transaction`.`void` = 0
GROUP BY
account_id
) AS Billed ON Billed.account_id = Account.id
LEFT JOIN
(SELECT
`account_id`,
(SUM(`Transaction`.`debit`) - SUM(`Transaction`.`credit`)) as amount,
COUNT(id) AS items
FROM
`transactions` AS `Transaction`
WHERE
`Transaction`.`statement_id` = 0 AND
`Transaction`.`void` = 0
GROUP BY
account_id
) AS Pending ON Pending.account_id = Account.id
LEFT JOIN
(SELECT
`account_id`,
MAX(Statement.statement_date) AS latest
FROM
`statements` AS `Statement`
WHERE
`Statement`.`void` = 0
GROUP BY
account_id
) AS Stmnt ON Stmnt.account_id = Account.id
GROUP BY
account.id
HAVING
Billed.balance > 0 OR
Pending.pending_ct > 0
ORDER BY
account_name ASC
I'm having difficulty successfully translating this into CakePHP 2.1 find or paginate-friendly options.
Any thoughts would be greatly appreciated.
Related
I have two tables from which the queries to be executed below is the query which have written, need help in joining the link between the query
select FIRST_NAME+ ' '+ LAST_NAME as FULL_NAME,PHONE,EMAIL
FROM PROFILES
WHERE PROFILE_ID IN
((
SELECT PROFILE_ID
FROM PROFILES
WHERE MARITIAL_STATUS= 'Y' ) and
( SELECT PROFILE_ID
FROM TENANCY_HISTORIES
WHERE RENT> '9000'));
You are using and in the list of ID's output for the in clause. Try as following:
select FIRST_NAME+ ' '+ LAST_NAME as FULL_NAME,PHONE,EMAIL
FROM PROFILES
WHERE
(PROFILE_ID IN
(
SELECT PROFILE_ID
FROM PROFILES
WHERE MARITIAL_STATUS= 'Y' ) or PROFILE_ID IN
( SELECT PROFILE_ID
FROM TENANCY_HISTORIES
WHERE RENT> '9000'));
I am writing this query with nested subquery to find PREPARED_BY, VERIFIED_BY, AUTHORIZED_BY depending on CONDATE from Expenditure table, but in my sub query the Expenditure table object CONDATE is not recognized and throws this error :
ORA-00904: "EX"."CONDATE": invalid identifier.
Code:
SELECT ex.conno,
ex.itemno,
ex.adv_no || ' ' || to_char(ex.condate, 'DD-MON-YYYY') chequenodate,
ex.conname,
ex.apaid,
ex.dpayment,
gf.gf_name,
expenditure_type,
ex.off_code,
ofc.officename,
ex.remarks,
(SELECT prepared_by
FROM (SELECT prepared_by
FROM authorization
WHERE (pre_last_date >= ex.condate OR pre_last_date IS NULL)
AND project_id = 128
ORDER BY id ASC)
WHERE rownum = 1) AS prepared_by,
(SELECT verified_by
FROM (SELECT verified_by
FROM authorization
WHERE (ve_last_date >= ex.condate OR ve_last_date IS NULL)
AND project_id = 128
ORDER BY id ASC)
WHERE rownum = 1) AS verified_by,
(SELECT authorized_by
FROM (SELECT authorized_by
FROM authorization
WHERE (au_last_date >= ex.condate OR au_last_date IS NULL)
AND project_id = 128
ORDER BY id ASC)
WHERE rownum = 1) AS authorized_by
FROM expenditure ex
INNER JOIN officecode ofc
ON ofc.off_code = ex.off_code
INNER JOIN coa_category ca
ON ca.coa_cat_id = ex.coa_cat_id
INNER JOIN g_fund_type gf
ON gf.gf_type_id = ca.gf_type_id
WHERE ex.conno = 'MGSP/PMU/NON/145'
AND ex.itemno = 149;
The problem you're experiencing is that parent table can only be referenced by a subquery one level down. You're trying to access columns from the parent table in the subquery two levels down, hence why you're getting the error.
In order to access the parent column in your subquery, you're going to need to rewrite it so that it's only one level down.
This can be achieved by using the KEEP FIRST/LAST aggregate function, e.g.:
SELECT ex.conno,
ex.itemno,
ex.adv_no || ' ' || to_char(ex.condate, 'DD-MON-YYYY') chequenodate,
ex.conname,
ex.apaid,
ex.dpayment,
gf.gf_name,
expenditure_type,
ex.off_code,
ofc.officename,
ex.remarks,
(SELECT MAX(a.prepared_by) KEEP (dense_rank FIRST ORDER BY a.id ASC)
FROM authorizatiion a
WHERE (a.pre_last_date >= ex.condate OR a.pre_last_date IS NULL)
AND a.project_id = 128) prepared_by,
(SELECT MAX(a.verified_by) KEEP (dense_rank FIRST ORDER BY a.id ASC)
FROM authorizatiion a
WHERE (a.ve_last_date >= ex.condate OR a.ve_last_date IS NULL)
AND a.project_id = 128) verified_by,
(SELECT MAX(a.authorized_by) KEEP (dense_rank FIRST ORDER BY a.id ASC)
FROM authorizatiion a
WHERE (a.au_last_date >= ex.condate OR a.au_last_date IS NULL)
AND a.project_id = 128) authorized_by
FROM expenditure ex
INNER JOIN officecode ofc ON ofc.off_code = ex.off_code
INNER JOIN coa_category ca ON ca.coa_cat_id = ex.coa_cat_id
INNER JOIN g_fund_type gf ON gf.gf_type_id = ca.gf_type_id
WHERE ex.conno = 'MGSP/PMU/NON/145'
AND ex.itemno = 149;
N.B. I have used MAX and FIRST here; this means that if there are multiple rows with the same lowest id, the highest value of the prepared_by column will be used. You could change this to MIN if you wanted the lowest value. This is only relevant if you have more than one row per id, otherwise it simply returns the value of the prepared_by column for the lowest id.
I have a peewee query that looks like this:
toptx24h = Transaction.select(fn.MAX(Transaction.amount).alias('amount'), User.user_name).join(User,on=(User.wallet_address==Transaction.source_address)).where(Transaction.created > past_dt).limit(1)
My understanding is this should be equivalent to:
select MAX(t.amount) as amount, u.user_name from transaction t inner join user u on u.wallet_address = t.source_address where transaction.created > past_dt limit 1
My question is how to I access the results user_name and amount
When I try this, I get an error saying top has no attribute named amount
for top in toptx24h:
top.amount # No such attribute amount
I'm just wondering how i can access the amount and user_name from the select query.
Thanks
I think you need a GROUP BY clause to ensure you're grouping by User.username.
I wrote some test code and confirmed it's working:
with self.database.atomic():
charlie = TUser.create(username='charlie')
huey = TUser.create(username='huey')
data = (
(charlie, 10.),
(charlie, 20.),
(charlie, 30.),
(huey, 1.5),
(huey, 2.5))
for user, amount in data:
Transaction.create(user=user, amount=amount)
amount = fn.MAX(Transaction.amount).alias('amount')
query = (Transaction
.select(amount, TUser.username)
.join(TUser)
.group_by(TUser.username)
.order_by(TUser.username))
with self.assertQueryCount(1):
data = [(txn.amount, txn.user.username) for txn in query]
self.assertEqual(data, [
(30., 'charlie'),
(2.5, 'huey')])
I am new in this cassandra database using with nodejs.
I have user_activity table. In this table data will insert based on user activity.
Also I have some user list. I need to fetch the data in that particular users and last record.
I don't interest to put the query in for loop. Have any other idea to achieve this?
Example Code:
var userlist = ["12", "34", "56"];
var query = 'SELECT * FROM user_activity WHERE userid IN ?';
server.user.execute(query, [userlist], {
prepare : true
}, function(err, result) {
console.log(results);
});
How to get the user lists for last one ?
Example:
user id = 12 - need to get last record;
user id = 34 - need to get last record;
user id = 56 - need to get last record;
I need to get these 3 records.
Table Schema:
CREATE TABLE test.user_activity (
userid text,
ts timestamp,
clientid text,
clientip text,
status text,
PRIMARY KEY (userid, ts)
)
It is not possible if you use the IN filter.
If it is a single user_id filter you can apply order by. Of course you need a column for inserted/updated time. So query will be like this:
SELECT * FROM user_activity WHERE user_id = 12 ORDER BY updated_at LIMIT 1;
You can put N value to get number of records
SELECT * FROM user_activity WHERE userid IN ? ORDER BY id DESC LIMIT N
I am running a query with Oracle:
SELECT
c.customer_number,
COUNT(DISTINCT o.ORDER_NUMBER),
COUNT(DISTINCT q.QUOTE_NUMBER)
FROM
Customer c
JOIN Orders o on c.customer_number = o.party_number
JOIN Quote q on c.customer_number = q.account_number
GROUP BY
c.customer_number
This works beautifully and I can get the customer and their order and quote counts.
However, not all customers have orders or quotes but I still want their data. When I use LEFT JOIN I get this error from Oracle:
ORA-24347: Warning of a NULL column in an aggregate function
Seemingly this error is caused by the eventual COUNT(NULL) for customers that are missing orders and/or quotes.
How can I get a COUNT of null values to come out to 0 in this query?
I can do COUNT(DISTINCT NVL(o.ORDER_NUMBER, 0)) but then the counts will come out to 1 if orders/quotes are missing which is no good. Using NVL(o.ORDER_NUMBER, NULL) has the same problem.
Try using inline views:
SELECT
c.customer_number,
o.order_count,
q.quote_count
FROM
customer c,
( SELECT
party_number,
COUNT(DISTINCT order_number) AS order_count
FROM
orders
GROUP BY
party_number
) o,
( SELECT
account_number,
COUNT(DISTINCT quote_number) AS quote_count
FROM
quote
GROUP BY
account_number
) q
WHERE 1=1
AND c.customer_number = o.party_number (+)
AND c.customer_number = q.account_number (+)
;
Sorry, but I'm not working with any databases right now to test this, or to test whatever the ANSI SQL version might be. Just going on memory.