How to use correct count distinct - Snowflake - sql

I have the below query were I would like to get the number of distinct users who have logged in within a period of a year.
Im trying the below:
select
'Spain' as "COUNTRY"
, 'Snowflake' as "TECHNOLOGY"
, year(event_timestamp) as "YEAR"
, month(event_timestamp) as "MONTH"
, 'USERS_LOGIN' as "KIND"
, distinct count(user_name) as "AMOUNT"
from snowflake.acount_usage.login_history
group by year(event_timestamp), month(event_timestamp);
However, if I try this query I don't get the result I want because the distinct clause and the event_timestamp kind of data seems to not allow this kind of execution.
Does anyone have any advice, please? Thank you in advance.

distinct count(user_name) will just give you one result, the count, the distinct here is irrelevant. if you want a count of distinct usernames change the code to:
select
'Spain' as "COUNTRY"
, 'Snowflake' as "TECHNOLOGY"
, year(event_timestamp) as "YEAR"
, month(event_timestamp) as "MONTH"
, 'USERS_LOGIN' as "KIND"
, count(distinct user_name) as "AMOUNT"
from snowflake.acount_usage.login_history
group by year(event_timestamp), month(event_timestamp);
then the group by will play ball.

Related

No function exists to perform desired grouping and aggregation

I've run into a conundrum I was hoping someone could help me out with. I have a table with the following fields:
SalesPeriod, SalesRep, Contract, MarginPerProduct, ProductSold
I have to multiply the MarginPerProduct and ProductSold to get 'TotalMargin'
Here is an example of the code I am trying to make work:
SELECT
SalesPeriod
, SalesRep
, Contract
, MarginPerProduct*ProductSold as 'TotalMargin'
FROM
tblSales
GROUP BY
SalesPeriod
, SalesRep
, Contract
Of course, the multiplied columns are invalid because they are not part of the grouping, plus there's no aggregate function being used.
Is there a way to accomplish this type of grouping when using a non recognized aggregation?
Thanks for your help.
Presumably, you want sum():
SELECT SalesPeriod, SalesRep, Contract,
SUM(MarginPerProduct * ProductSold) as TotalMargin
FROM tblSales
GROUP BYSalesPeriod, SalesRep, Contract;
Why not just this
SELECT
SalesPeriod
, SalesRep
, Contract
, TotalMargin = MarginPerProduct*ProductSold
FROM
tblSales
If you want the TotalMargin to be summed up for each SalesPeriod\SalesRep\Contract then
SELECT
SalesPeriod
, SalesRep
, Contract
, TotalMargin = sum(MarginPerProduct*ProductSold)
FROM
tblSales
GROUP BY
SalesPeriod
, SalesRep
, Contract

Access Query subtract 2 different column from different row in same table with same ID

I have a table deposit which have column Refund_amt ,Deposit_amt having different Rows with same GR_no . here my question is ,I want to subtract deposit_amt column from Refund_amt
I tried various alternative in query but didn't succeed
My query :
SELECT d.Gr_no
, d.Rec_No
, d.Deposite_Amt
, d.penalty_Amt
, d.Refund_Amt - Refund
, s.Name
, s.cur_std
, cur_div
From
( select d.Refund_Amt refund
from deposite d
, std_gr s
where d.Gr_no = s.Gr_no )
Result would look like this in final total column :
Thank you
You are looking for an aggregation per std_gr: the sum of the deposites minus the sum of the refunds. One way is to do this aggregation in a subquery and join this subquery to your table.
select
d.*, sums.final_total
from deposite d
join
(
select std_gr, nz(sum(deposite_amt),0) - nz(sum(refund_amt),0) as final_total
from deposite
group by std_gr
) as sums on sums.std_gr = d.std_gr
order by d.rec_no;

Produce one row in an Oracle sql query using group_by

I'm using Oracle 10.g. I have a table, LIB_BOOK, containing a listing of books in a library. There are multiple copies of many of the books. I'd like to produce a report that lists all the books with more than one copy. I've constructed a query that lists the books, but I can't find a way to get only one row for the result.
Select
title
, copy_number
, isbn_10
, category
, book_pk
, max(copy_number)
From LIB_BOOK
Group by
title
, copy_number
, isbn_10
, category
, book_pk
Order by copy_number desc
;
As you can see in the data result below, I get the results for "Conversations with God - Book 1" listed seven times. I'd like that book to be listed only once with a "7" as the copy_number.
I took the first 32 rows of the query result, exported it to Excel and pasted the image below.
How do I construct a query to result in only one row per book, and avoid books with only one copy (copy_number > 1)?
Thanks for looking at this.
Try this
Select
title
, copy_number
, isbn_10
, category
, book_pk
, copy_number
From LIB_BOOK lib
join (select title,max(copy_number) as maxcopynumber
from LIB_BOOK group by title) maxcopy on lib.title = maxcopy.title and lib.copy_number = maxcopy.maxcopynumber
Order by lib.copy_number desc
;
You need to remove copy_number() and book_pk from the group by:
Select title, isbn_10, category,
max(copy_number)
From LIB_BOOK
Group by title, isbn_10, category
Order by max(copy_number) desc;
I'm not sure what you want for book_pk, so I just removed it from the select.
It looks like you only want to list the duplicate books, no matter what category, copy number etc. So group by book (isbn and title) and count, then remove books with less than 2 copies in your HAVING clause:
select
title
, isbn_10
, max(copy_number) as max_copy_number
, count(*) as number_of_copies
from lib_book
group by title, isbn_10
having count(*) > 1
order by count(*) desc;
You can use the unsupported WM_CONCAT to list categories and book pks:
select
title
, isbn_10
, max(copy_number) as max_copy_number
, count(*) as number_of_copies
, wm_concat(distinct category) as categories
, wm_concat(book_pk) as book_pks
...
Note that you are getting getting multiple rows because some of the fields which you are grouping by are different for the same book like copy number and book pk ...
Please try the below query:
SELECT *
FROM (SELECT TITLE,
COPY_NUMBER,
ISBN_10,
CATEGORY,
BOOK_PK,
COPY_NUMBER,
ROW_NUMBER() OVER (PARTITION BY ISBN ORDER BY COPY_NUMBER DESC) RN
FROM LIB_BOOK) X
WHERE RN = 1

the microsoft access database engine cannot find the input table or query 'Test'. Make sure it exists and that its name is spelled correctly

getting the following error in access 2010,
the Microsoft access database engine cannot find the input table or query 'Test'.
Make sure it exists and that its name is spelled correctly.
when running,
SELECT
TEST.[CATEGORY CODE] AS CATEGORYCODE
, TEST.[SAMPLE COMPOSITION] AS SAMPLECOMPOSITION
, Sum(TEST.[WPI]) AS [SumOfWPI]
, Sum(TEST.[Mean Freq Year Fav]) AS [SumOfMean Freq Year Fav]
FROM
(
SELECT *
FROM DATA1
WHERE DATA1.[CATEGORY CODE] IN (
SELECT DISTINCT CODES.[CATEGORY CODE]
FROM CODES
)
UNION ALL
SELECT *
FROM DATA2
WHERE DATA2.[CATEGORY CODE] IN (
SELECT DISTINCT CODES.[CATEGORY CODE]
FROM CODES
)
) AS TEST
WHERE TEST.[COUNTRY] = 'UNITED STATES'
AND TEST.[SAMPLE COMPOSITION] IN (
SELECT DISTINCT TEST.[SAMPLE COMPOSITION]
FROM TEST
)
AND TEST.[CATEGORY CODE] IN (
SELECT DISTINCT CODES.[CATEGORY CODE]
FROM CODES
)
GROUP BY TEST.[CATEGORY CODE], TEST.[SAMPLE COMPOSITION]
ORDER BY TEST.[CATEGORY CODE];
I am creating a 4th table TEST using union all by clubbing 2 tables Data1 & Data2 and making sure only the records are for Category codes taken from Codes tables. Any ideas why its giving me this error?
if i remove this line which is a self-join to the table created by union all:
AND TEST.[SAMPLE COMPOSITION] IN (SELECT DISTINCT TEST.[SAMPLE COMPOSITION] FROM TEST)
i am able to run the query....
Also, right now i have specified COUNTRY = "UNITED STATES". But how do i specify COUNTRY="<>UNITED STATES" OR COUNTRY= All Countries, so that i can get Totals for each?
right now i am doing multiple criteria Autofilters to achieve this, but it is taking 1.5 days as the data after clubbing the 2 tables is ~92000 records. So, trying access to achieve the same. If someone can help me, then i can send a sample file containing data.
You can't reference TEST until it is created, and you're creating it as a result of the query. You're going to have to do it with 2 queries, since you need all the results in your UNION ALL.
COUNTRY <> "UNITED STATES" will answer your second question.

Building a Postgresql View Over a View

I've got a problem with one of my clients for OpenERP. I need to build a custom object for them, cause they have a problem where sometimes they get returned products after they have been sold. So I need to mark that as negative and subtract from the total sold from before.
SELECT sum(rsm1.product_qty_out) as "out"
, sum(rsm2.product_qty_in) as "in"
, rsm2.location_id
, rsm2.product_id
, rsm2.month
from report_stock_move as rsm1, report_stock_move as rsm2
where rsm2.location_id in (
select id
from stock_location
where "name" = 'Consumers'
)
and rsm1.location_id not in (
select id
from stock_location
where "name" = 'Consumers'
)
and rsm1.location_dest_id = rsm2.location_id
and rsm2.location_dest_id = rsm1.location_id
and rsm1.state = 'done' -- both are in done state
and rsm2.state = rsm1.state
group by rsm2.location_id, rsm2.month, rsm2.product_id
;
Anyone have any ideas? Also, I keep getting different results depending upon which table I use for the grouping. Why is that?
EDIT
Sorry, in my haste to solve this, I seem to have made my point clear. report_stock_moves that have a location_id of Consumers from a stock_location table need to be negative and summed up into report_stock_moves that have location_id of another place, but Consumer is the location_dest_id.
Example:
location_id = Some Place (actually ID of stock_location of course)
product_qty = 8
location_dest_id Consumers
date = 2012-07-02
location_id = Consumer
product_qty = 4
location_dest_id Some Place
date = 2012-07-04
Here are two record examples. They have different dates attached to them, so I'd probably want to take the max date, or the date of the returns(from Consumer to Some Place) if I want to union or group them so that when they are put together, i get 4, instead of say 8 if I didn't put them together and only look at what is going into Consumers.
In case anyone struggles with this for later. I'll paste my answer here. If anyone can help me explain about why union all in here seems to work, I'm all ears. I can do simple SQL, but I don't know much about how unions work, especially in case like this.
select max(total.id) as id,
sum(total.product_qty) as product_qty,
total.location_id as location_id,
total.date as "date",
total.year as year,
total.month as month,
total.day as day,
total.product_id as product_id
from (
-- From Consumer back to location
select -max(id) as id,
-sum(product_qty) as product_qty,
location_dest_id as location_id,
"date", year, month, day, product_id
from report_stock_move
where location_id in (
select id
from stock_location
where "name" = 'Consumers'
)
and "state" = 'done'
group by location_dest_id, "date", year, month, day, product_id
union all
-- From Location to Consumer
select max(id) as id,
sum(product_qty) as product_qty,
location_id, "date", year, month, day, product_id
from report_stock_move
where location_id not in (
select id
from stock_location
where "name" = 'Consumers'
)
and "state" = 'done'
and location_dest_id in (
select id
from stock_location
where "name" = 'Consumers'
)
group by location_id, "date", year, month, day, product_id
) as total
group by location_id, "date", year, month, day, product_id