Thanks for taking the time to read my question.
Imagine a situation where a customer is given a free gift if they open an account. Some ‘customers’ open an account to get the free gift, but never add any money to their account. Other ‘customers’ open accounts, get the free gift and also fund their accounts by adding money to it.
I need to compare the funded accounts to the overall count of all customers.
Things at first appeared quite easy …
SELECT Audits.AuditDate, Count(Audits.NickName) AS AllAccounts
FROM Audits
Group By Audits.AuditDate
This obviously gives me the count of all accounts on a daily basis.
To get the ‘Funded’ count, I do …
SELECT Audits.AuditDate, Count(Audits.NickName) AS Funded
FROM Audits
WHERE Audits.CurrGBP > 0
GROUP BY Audits.AuditDate;
This time I get the count of the ‘Funded’ accounts.
Now, this is where I get stuck … I want both counts from the same query so my results would be like this …
AuditDate (DD/MM/YYYY) AllAccounts Funded
01/01/2012 50 45
02/01/2012 60 50
03/01/2012 70 55
Something is telling me I need to use a Sub Query, but after googling a few pages. Sub Queries are baffling to me.
May I ask for some help please ? Can you show me how to write a Sub Query to give me the results I need.
Regards,
John.
PS - My Audits table has the following fields, Audit_ID, Audit_Date, NickName, CurrGBP and I am using MS Access 2010.
Cant remember if access supports case; or if IIF is the way to go... but something like...
A sub query isn't really needed, you can get the results in one query, just limit what you count when using a case or IIF.
Select A.AuditDate,
count (A.NickName) as AllAccounts,
sum(CASE when A.CurrGBP > 0 then 1 else 0 end) as Funded
FROM Audits A
GROUP BY A.AuditDate
if IIF
Select A.AuditDate,
count (A.NickName) as AllAccounts,
sum(IIF(A.CurrGBP >0,1,0)) as Funded
FROM Audits A
GROUP BY A.AuditDate
EDIT, was missing some commas in selects.
try this:
SELECT AuditA.AuditDate,
Count(AuditA.AllAcounts) as AllAccount,
iTable.iCount
FROM Audits as AuditA
INNER JOIN
(SELECT AuditB.Audit_ID, COUNT(AuditB.Audit_ID) as iCount
FROM Audit as AuditB
WHERE AuditB.CurrGBP > 0) as iTable
ON AuditA.Audit_ID = iTable.Audit_ID
Related
I was asked to assist with developing a report to retrieve a 25% sample of random transactions within a specific date range. I am not a programmer but I was able to devise the following fairly quickly:
SELECT TOP 25 PERCENT account.CID, account.ACCT, account.NAME, log.DATE, log.action_txt, log.field_nm, log.from_data, log.to_data, log.tran_id, log.init
FROM account INNER JOIN log ON account.ACCT = log.ACCT
GROUP BY account.CID, account.ACCT, account.NAME, log.DATE, log.action_txt, log.field_nm, log.from_data, log.to_data, log.tran_id, log.init
HAVING (((log.DATE) Between #2/7/2018# And #6/15/2018#) AND ((log.action_txt)="mod" Or (log.action_txt)="del") AND ((log.init)="J1X"
ORDER BY log.tran_dt
This returns 25% of the records within the date range. Each record row is unique but each account number potentially has multiple records on each day. In some cases the records have the same date and tran_id as well.
Upon further discussion with the requester, he actually wants to see all of the transactions for 25% of the accounts that have activity on each day within the date range. Thus if there were 100 accounts on 3/1/2018 with records in this table, he wants to see all of the transactions for 25 of those accounts; if there were 60 accounts on 3/2/2018 with records in this table, he wants to see all of the transactions for 15 of those accounts; and so on.
I was thinking that an Access module would work best in this scenario as I believe there are multiple parts to this. I figured that I need a function to loop through the date range and for each day:
1. Count the account numbers only one time
2. Return all of the transactions for 25% of the total accounts
But as I mentioned, I am not a programmer and I am exhausted from searching possible solutions for the many parts.
I think the key to your question is that you only really need a pseudo random selection of results for your report. So you can force the Random number generator to reorder your results based on a value in the record and the current time.
Something like this should work - I assume your actiontxt field is a text field and pull out the length of each field and apply that to current date/time to create a pseudo random number that can be sorted.
All I really do is change your ORDER BY line
See if this works for you
SELECT TOP 25 PERCENT
account.CID, account.ACCT, account.NAME, log.DATE, log.action_txt, log.field_nm, log.from_data,
log.to_data, log.tran_id, log.init
FROM account
INNER JOIN log ON account.ACCT = log.ACCT
GROUP BY account.CID, account.ACCT, account.NAME, log.DATE, log.action_txt, log.field_nm, log.from_data, log.to_data, log.tran_id, log.init
HAVING (((log.DATE) Between #2/7/2018# And #6/15/2018#) AND ((log.action_txt)="mod" Or (log.action_txt)="del") AND ((log.init)="J1X"
ORDER BY Rnd(CLng(Now()*Len(log.action_txt))-(Now()*Len(log.action_txt)));
Modified similar idea from other StackOverflow question and response
I've got a table called spending (actually in BigQuery, though I don't think that's necessarily relevant for this question) that is about 2.9GB and 19 million rows.
The data structure is like this:
product,org,spend,to_include,proportion_overseas
----------------------------------
SK001,03V,"Yes",0.1
SK002,03V,2.4,"Yes",0.1
SK001,O3T,66.1,"No",0.47
SK002,03T,87.1,"No",0.47
SK001,04C,16.1,"Yes",0
SK002,04C,27.1,"Yes",0
...
For info, it is slightly denormalised, in that to_include and proportion_overseas are actually properties of each organisation.
Now I want to work out, for each product:
the total amount that all organisations with no overseas spending spent on that product, and
the total amount that all organisations with non-zero overseas spending spent on that product.
I also only want to include in this calculation only rows where to_include='Yes'.
I'm not sure what the best approach to do this is in SQL. I don't mind whether I end up with two tables, or one.
I know how to get all spending by code, for all relevant rows:
SELECT product, SUM(spend)
FROM spending
WHERE to_include='Yes'
GROUP BY product;
But what I don't know is how to split each row into two groups: one group where proportion_overseas=0 and one group where proportion_overseas>0.
I don't think 'subquery' is the right term, so I don't really know what to Google for!
You can use conditional aggregation:
SELECT product, SUM(spend),
SUM(CASE WHEN proportion_overseas = 0 THEN spend ELSE 0 END) as not_overseas,
SUM(CASE WHEN proportion_overseas > 0 THEN spend ELSE 0 END) as overseas
FROM spending
WHERE to_include='Yes'
GROUP BY product;
I have been recently working with GOOD-DATA platform. I don't have that much experience in MAQL, but I am working on it. I did some metric and reports in GOOD-DATA platform. Recently I tried to create a metric for calculating Total Buyers,First Time Buyers and Repeating Buyers. I created these three reports and working perfect.But when i try to add a order date parent filter the first time buyers and repeating buyers value getting wrong. please have Look at Following queries.
I can find out the correct values using sql queries.
MAQL Queries:
TOTAL ORDERS-
SELECT COUNT(NexternalOrderNo) BY CustomerNo WITHOUT PF
TOTAL FIRSTTIMEBUYERS-
SELECT COUNT(CustomerNo) WHERE (TOTAL ORDER WO PF=1) WITHOUT PF
TOTAL REPEATINGBUYERS-
SELECT COUNT(CustomerNo) WHERE (TOTAL ORDER WO PF>1) WITHOUT PF
Can any one suggest a logic for finding these values using MAQL
It's not clear what you want to do. If you could provide more details about the report you need to get, it would be great.
It's not necessary to put "without pf" into the metrics. This clause bans filter application, so when you remove it, the parent filter will be used there. And you will probably get what you want. Specifically, modify this:
SELECT COUNT(CustomerNo) WHERE (TOTAL ORDER WO PF>1) WITHOUT PF
to:
SELECT COUNT(CustomerNo) WHERE (TOTAL ORDER WO PF>1)
The only thing you miss here is "ALL IN ALL OTHER DIMENSIONS" aka "ALL OTHER".
This keyword locks and overrides all attributes in all other dimensions—keeping them from having any affect on the metric. You can read about it more in MAQL Reference Guide.
FIRSTTIMEBUYERS:
SELECT COUNT(CustomerNo)
WHERE (SELECT IFNULL(COUNT(NexternalOrderNo), 0) BY Customer ID, ALL OTHER) = 1
REPEATINGBUYERS:
SELECT COUNT(CustomerNo)
WHERE (SELECT IFNULL(COUNT(NexternalOrderNo), 0) BY Customer ID, ALL OTHER) > 1
I am discovering SQL as I have to build queries in my new company.I have understood the basic but here is where I am stuck, maybe you could help me figure this out :
I would like to mention a product as unprocurable if sellers rejected my orders twice. Tricky part I aggregate the furniture orders for all our local offices, therefore even though I sent my purchase order(s) to one unique seller (the one with the best offer at the moment) I might have multiple lines for each item (one per office)
See below table for purchase orders, see REF1 item should be set as unprocurable as both on 21 and 31 december my orders have been rejected (no matter the seller)
http://i.stack.imgur.com/r3W3E.jpg
So to put it in logic I would like to have something like this:
For each items with 2 latest purchase orders that were both made at different dates and rejected(0 value in the table) THEN attach a note to it saying "unprocurable" else put as procurable.
IF it was only 1 value I think I could go with
Select
item
, MAX(date)
, case
when confirmed_units = 0
then 'Unprocurable'
else 'procurable'
end
From
purchase_table
Where
date between TO_DATE('01/01/2013', 'MM/DD/YYYY') AND TO_DATE('{RUN_DATE_YYYY/MM/DD}', 'YYYY/MM/DD')
But now I need to check the two latest purchase orders and that are not from the same day.
I am a bit lost, could you give a hand please?
Thanks !
Your question is a little unclear... have you tried using something along the lines of:
SELECT TOP 2 etc, etc... order by [column]
This is a pretty basic problem and for whatever reason I can't find a reasonable solution. I'll do my best to explain.
Say you have an event ticket (section, row, seat #). Each ticket belongs to an attendee. Multiple tickets can belong to the same attendee. Each attendee has a worth (ex: Attendee #1 is worth $10,000). That said, here's what I want to do:
1. Group the tickets by their section
2. Get number of tickets (count)
3. Get total worth of the attendees in that section
Here's where I'm having problems: If Attendee #1 is worth $10,000 and is using 4 tickets, sum(attendees.worth) is returning $40,000. Which is not accurate. The worth should be $10,000. Yet when I make the result distinct on the attendee, the count is not accurate. In an ideal world it'd be nice to do something like
select
tickets.section,
count(tickets.*) as count,
sum(DISTINCT ON (attendees.id) attendees.worth) as total_worth
from
tickets
INNER JOIN
attendees ON attendees.id = tickets.attendee_id
GROUP BY tickets.section
Obviously this query doesn't work. How can I accomplish this same thing in a single query? OR is it even possible? I'd prefer to stay away from sub queries too because this is part of a much larger solution where I would need to do this across multiple tables.
Also, the worth should follow the ticket divided evenly. Ex: $10,000 / 4. Each ticket has an attendee worth of $5,000. So if the tickets are in different sections, they take their prorated worth with them.
Thanks for your help.
You need to aggregate the tickets before the attendees:
select ta.section, sum(ta.numtickets) as count, sum(a.worth) as total_worth
from (select attendee_id, section, count(*) as numtickets
from tickets
group by attendee_id, section
) ta INNER JOIN
attendees a
ON a.id = ta.attendee_id
GROUP BY ta.section
You still have a problem of a single attendee having seats in multiple sections. However, you do not specify how to solve that (apportion the worth? randomly choose one section? attribute it to all sections? canonically choose a section?)
Using jsonb_object_agg:
select
tickets.section,
count(tickets.*) as count,
(
SELECT SUM(value::int4)
FROM jsonb_each_text(jsonb_object_agg(attendees.id, attendees.worth))
) as total_worth
from
tickets
INNER JOIN
attendees ON attendees.id = tickets.attendee_id
GROUP BY tickets.section