Access - SQL Query Date wise with selection of column summarized value - sql

Below is my source Data
by using below query I can get summarized data for '17-09-2016'
SQL Query :-
SELECT key_val.A, key_val.B, key_val.C, key_val.D, Sum(IIf(key_val.Store_date=#9/17/2016#,key_val.Val,0)) AS [17-09-2016]
FROM key_val
GROUP BY key_val.A, key_val.B, key_val.C, key_val.D;
but I am looking output suppose to look like this way.
Specifically= I need summarized data for column a,b,c and for '17-09-2016' dateIn excel we will apply sumifs formula to get desired output but in Access - SQL I am not getting how to form the query to get the same data.
Can any one assist me how to acheive above result by using Access Query?
Specifically= I need summarized data for column a,b,c and for '17-09-2016' date

I'm not sure where you get the 34 figure from - the sum of the first two rows even though the values in A, B, C & D are different (so the grouping won't work)?
Making an assumption that you want the values summed where all the other fields are equal (A, B, C, D & Store_Date):
This query will give you the totals, but not in the format you're after:
SELECT A, B, C, D, SUM(val) As Total, Store_Date
FROM key_val
WHERE Store_date = #9/17/2016#
GROUP BY A,B,C,D, Store_Date
This SQL will give you the same, but for all dates (just remove the WHERE clause).
SELECT A, B, C, D, SUM(val) As Total, Store_Date
FROM key_val
GROUP BY A,B,C,D, Store_Date
ORDER BY Store_Date
This will give the exact table shown in your example:
TRANSFORM Sum(val) AS SumOfValue
SELECT A, B, C, D
FROM key_val
WHERE Store_date = #9/17/2016#
GROUP BY A,B,C,D,val
PIVOT Store_Date
Again, just remove the WHERE clause to list all dates in the table:

Related

PostgreSQL Error more than one row returned by a subquery used as an expression

I have a problem with a data query where I query a single column like this:
SELECT a.ad_morg_key, count(a.sid_mpenduduk_key) AS total_population
FROM sid_mpenduduk a
GROUP BY a.ad_morg_key;
and it really works. But when I query with multiple columns with a query like this:
SELECT a.ad_morg_key, b."name",
count(b.sid_magama_key) AS total,
count(b.sid_magama_key)::float / (SELECT count(a.sid_mpenduduk_key)
FROM sid_mpenduduk a
GROUP BY a.ad_morg_key)::float * 100::float AS percentage,
(SELECT count(a.sid_mpenduduk_key) FROM sid_mpenduduk a GROUP BY a.ad_morg_key) AS total_population
FROM sid_mpenduduk a
INNER JOIN sid_magama b ON a.sid_magama_key = b.sid_magama_key
GROUP BY a.ad_morg_key, b."name";
But it fails with:
ERROR: more than one row returned by a subquery used as an expression
I want the final result like this :
Your subquery is grouped by a.ad_morg_key so it will get you a row for each different value of a.ad_morg_key.
In general terms each subquery in a SELECT statement should return a single value. Suppose you have the following table called A.
A_key
A_value
A1
200
A2
200
If you execute
SELECT (SELECT A_KEY FROM A) as keys
FROM A
the subquery (SELECT A_KEY FROM A) returns
A_key
A1
A2
so what should be the value for keys?
SQL cannot handle this decision so you should pick one of the values or aggregate them into a single value.
Use a correlation clause instead:
(SELECT count(a.sid_mpenduduk_key)
FROM sid_mpenduduk a2
WHERE a2.ad_morg_key = a.ad_morg_key
) AS total_population
I'm not sure if the subquery is really necessary. So, you might consider asking a new question with sample data, desired results, and a clear explanation of what you are trying to do.
You're getting burned by
GROUP BY ...
(SELECT count(a.sid_mpenduduk_key)
FROM sid_mpenduduk a
GROUP BY a.ad_morg_key) AS total_population
because the outer GROUP BY wants a scalar, but the subquery is producing a count for each a.ad_morg_key.
I don't write my queries that way. Instead, produce a virtual table,
SELECT a.ad_morg_key, b."name",
...
JOIN
(SELECT ad_morg_key,
count(sid_mpenduduk_key) as N
FROM sid_mpenduduk
GROUP BY ad_morg_key) AS morgs
on ad_morg_key = morgs.ad_morg_key
That way, you have the count for each row as N, and you can divide at will,
count(b.sid_magama_key)::float / morgs.N
and, if you get tripped up, you'll have many more rows than you expected instead of an error message.

Adding a "calculated column" to BigQuery query without repeating the calculations

I want to resuse value of calculated columns in a new third column.
For example, this query works:
select
countif(cond1) as A,
countif(cond2) as B,
countif(cond1)/countif(cond2) as prct_pass
From
Where
Group By
But when I try to use A,B instead of repeating the countif, it doesn't work because A and B are invalid:
select
countif(cond1) as A,
countif(cond2) as B,
A/B as prct_pass
From
Where
Group By
Can I somehow make the more readable second version work ?
Is this first one inefficient ?
You should construct a subquery (i.e. a double select) like
SELECT A, B, A/B as prct_pass
FROM
(
SELECT countif(cond1) as A,
countif(cond2) as B
FROM <yourtable>
)
The same amount of data will be processed in both queries.
In the subquery one you will do only 2 countif(), in case that step takes a long time then doing 2 instead of 4 should be more efficient indeed.
Looking at an example using bigquery public datasets:
SELECT
countif(homeFinalRuns>3) as A,
countif(awayFinalRuns>3) as B,
countif(homeFinalRuns>3)/countif(awayFinalRuns>3) as division
FROM `bigquery-public-data.baseball.games_post_wide`
or
SELECT A, B, A/B as division FROM
(
SELECT countif(homeFinalRuns>3) as A,
countif(awayFinalRuns>3) as B
FROM `bigquery-public-data.baseball.games_post_wide`
)
we can see that doing all in one (without a subquery) is actually slightly faster. (I ran the queries 6 times for different values of the inequality, 5 times was faster and one time slower)
In any case, the efficiency will depend on how taxing is to compute the condition in your particular dataset.

how to segment groups based on different criteria

I'm trying to assign test and control groups based on A to F columns values to the table below.
Eventually, I want a table look like below. If different zips have the same values for all columns, then assign half zips to test and half to control. If the total number of zips cannot be equally assigned, then give the extra zip to control.
You could use row_number() and mod():
select
t.*,
case when mod(
row_number() over(partition by A, B, C, D, E, F order by zip),
2
) = 0 then 'T' else 'C' end tc_group
from mytable t
row_number() assigns increasing numbers to records that share the same (A, B, C, D, E, F) values, ordered by increasing zip. We would assign even row numbers to testing group T, and uneven numbers to group C.
I think a stratified sample will do what you want:
select t.*,
(case when mod(row_number() over (order by a, b, c, d, e, f), 2) = 1
then 'C' else 'T'
end) as test_group
from t;
This is not exactly how you phrased the question, but it should have the same effect of splitting rows with the same values in the columns evenly in the two groups. When there are odd numbers, sometimes the extra will go to test and sometimes to control.
It is unclear from the question whether you want balanced control and test groups -- which is what I would expect. If you actually want all groups with odd numbers to go to control (as you suggest), then all the onesies will be in the control and that seems biased to me.

Google Query Language: filter by date

I'm trying to add a filter by date in a Google Visualization API query, but I'm doing something wrong with the syntax...
This is the code without the date filter:
query.setQuery('SELECT A, B, C, D, E, F, G where upper(A) like upper("keyword") or upper(F) like upper("keyword") order by B DESC');
I want to add an AND and also add the condition that date in ColB must be >= of 1st Aug 2016.
So I tried with:
query.setQuery('SELECT A, B, C, D, E, F, G where upper(A) like upper("keyword") or upper(F) like upper("keyword") AND upper(B) >= date "2016-08-01" order by B DESC');
But the syntax is probably wrong as the query gets interrupted.
If B is a date your error is:
Unable to parse query string for Function QUERY parameter 2: upper takes a text parameter
To solve it just remove upper function.
IF B is just a string then automatic type casting is done and query should run without problems.

Oracle-Complex sql view creation

I have a table like below:
For each disinct combination of ID and VALUE, I have several steps. For example, For the combination of A and B, I have three steps QC, LC and DR and so on for C and D. Now, I want a view like below:
That is, I want a column "OUTPUT" in the view where i have to put the first step after QC for each combination of ID and VALUE. For example, For A and B, first step after QC is LC and so OUTPUT value is LC. For C and D, there is no QC and so OUTPUT value is NA.
Can anyone please help me on this issue.
Thanks in advance.
In SQL, tables are inherently unordered. So, you need a column to specify the ordering. Let me assume that you have such a column, say StepOrder in the table. If so, then you can do what you want using analytic functions.
The lead() in the inner subquery returns the next step. The max() in the next subquery returns the value after QA, and the output max() spreads the value over all rows with the same id and value:
select id, value, step,
coalesce(max(qa_next) over (partition by id, value), 'NA') as "Output"
from (select t.*,
max(case when step = 'QA' then nextstep end) over (partition by id, value) as qa_next
from (select t.*,
lead(step) over (partition by id, value order by StepOrder) as nextStep
from table t
) t
) t