Month wise % share of the Categories and not cumulative - ms-access

I have a data where I want to calculate the % share of a category (Text column) however I want to exclude the blanks from the calculation and want to calculate the share month wise (Text column)
My query:
SELECT Category, Count(Category) AS CountOfCategory, Count([Category])/DCount("*","[Tablename]") AS MyPercent
FROM [Tablename]
GROUP BY Category;
Current sample outcome from the query looks like this.
My Table looks like this
| Month Text | Category |
|------------|----------|
| Dec'18 | A |
| Nov'18 | A |
| Dec'18 | A |
| Nov'18 | C |
| Dec'18 | A |
| Nov'18 | C |
| Dec'18 | B |
| Nov'18 | C |
Please help.

Your query doesn't match you data example but I guess this query should help:
SELECT a.[Month Text], a.Category, Count(a.Category),
Count(a.Category)/
(
SELECT Count(b.Category)
FROM yourtablename AS b
WHERE b.[Month Text] = a.[Month Text]
)
FROM yourtablename AS a
WHERE a.Category Is Not Null
AND a.Category<>""
GROUP BY a.[Month Text], a.Category;

Related

Grouping by a field, then counting occurrences based on the results from a separate table

This is tough to explain so I'll add tables in to hopefully catch the things I don't type out well.
I have a table of products each with a country id. I want to get the count of unique products for each country id. However there are a couple tables I want to join by to determine if the sku should be counted.
I have prods table that looks like this
| key_id | c_id | sku |
|-----------|--------|-------|
| 1 | 1 | ABC |
| 2 | 2 | ABC |
| 3 | 3 | ABC |
| 4 | 1 | DEF |
| 5 | 2 | DEF |
A filter table (in my code it's a few inner joins of a few tables, but the goal is to make something that works like this)
| sku | want_sku |
|-------|---------------|
| ABC | 0 |
| DEF | 1 |
and this is the desired end result of my query
| c_id | # of unique_skus |
|--------|----------------------|
| 1 | 1 |
| 2 | 1 |
| 3 | 0 |
This is what i've pieced together so far, but it's getting me the total # of skus so something is off.
SELECT
prods.c_id,
COUNT(DISTINCT prods.SKU)
FROM
prods
INNER JOIN
filter
ON filter.sku = prods.sku
WHERE
filter.want_sku = 1
GROUP BY
prods.c_id
This just gets me the max # of distinct skus and assigns that to each of the different c_id. Not sure quite exactly how to fix it. Any help/advice would be greatly appreciated, thanks!
I think you want a left join:
SELECT p.c_id,
COUNT(DISTINCT f.SKU)
FROM prods p LEFT JOIN
filter f
ON f.sku = p.sku AND
f.want_sku = 1
GROUP BY p.c_id;
Note: I don't think you need COUNT(DISTINCT), but that is how you phrased it.

Join/Merge Multiple Table with same column name

I want to join three tables respectively from the below SQLFiddle
http://sqlfiddle.com/#!9/5dd558/4
Now I want to create one table from this table based on date and Brand.
Like, I want data in this manner
Date, Brand, Series, Table_1_Viewers, Table_2_Viewers, Table_2_Viewers
and if data is not matched on the table then the field should be nulled.
What I have done
SELECT h.*,
a.`amazon_viewers` AS "Table_1_Viewers",
n.`views` AS "Table_2_Viewers",
FROM `Table-1` h
LEFT JOIN `Table-2` a
ON h.`date` = a.`date`
AND h.`brand` = a.`brand`
LEFT JOIN `Table-3` n
ON h.`date` = n.`date`
AND h.`brand` = n.`brand`
Obviously I am selecting data from table-1 so it will display brand column only from table-1 but how can I get all table's brand column name in one column and merge these tables.??
The output I want...
| Date | Brand | Series | Table_1_Viewers | Table_2_Viewers | Table_3_Viewers |
|:----------:|:--------:|:--------------:|:---------------:|:---------------:|:---------------:|
| 12/1/2018 | TEST | TEST_SERIES | 100 | | |
| 10/15/2018 | MTV | GOT | 1000 | | 1000 |
| 12/1/2018 | TEST | Viking | 485632 | 856325 | |
| 12/1/2018 | TEST | Another Series | | 200 | |
| 10/15/2018 | POGO | GOT | | 1000 | |
| 7/1/2019 | No_Match | TEST_SERIES | | | 100 |
| 12/1/2018 | TEST-5 | Viking | | | 953022 |
You can do union all with aggregation :
select t.Date, t.Brand, t.Series_name,
sum(case when table_view = 't1' then amazone_viewer else 0 end) as Table_1_Viewers,
. . .
from (select h.date, h.brand, h.series_name, h.amazone_viewer, 't1' as table_view
from `Table-1` h union all
select h1.date, h1.brand, h1.series, h1.viewes, 't2'
from `Table-2` h1 union all
. . .
) t
group by t.Date, t.Brand, t.Series_name;

Mysql group-concat is giving wrong output

My purchaseproduct table
+------------+------------+
| productids | quantities |
+------------+------------+
| 1,3,4,5 | 1,1,1,1 |
| 2,3,4,5 | 1,1,1,1 |
+------------+------------+
My product table
productsid | productsname |
+------------+-----------------------------+
| 1 | Phone |
| 2 | Laptop |
| 3 | Charger |
| 4 | Earphone |
| 5 | Camera |
I want to get product name based on productids in purchaseproduct table
Like below Out put is needed
Phone,Charger,Earphone,Camera (In row one)
Laptop,Charger,Earphone,Camera (In row two)
I tried this below statement and many other
select group_concat(p.productsname) from purchaseproducts as pp join products as p on find_in_set(p.productsid,pp.productids);
But the output I get is
Phone,Charger,Earphone,Camera,Laptop,Charger,Earphone,Camera (All in one row)
How can I achieve the output I need?
You can simply use DISTINCT inside the GROUP_CONCAT :
select pp.productsid , group_concat(DISTINCT p.productsname)
from purchaseproducts pp
join products p
on find_in_set(p.productsid,pp.productids);
GROUP BY pp.productsid

SQL Query for selecting multiple rows but highest value for each PK

I know that the title sounds horrible but I have no idea how to summarize it better. I'm pretty sure that somebody had the same problem before but I couldn't find anything. RDBMS: MySQL.
Problem:
I have the following (simplified) table:
+------+------------+---------------------------------+
| name | date | score |
+------+------------+---------------------------------+
| A | 01.01.2015 | 1 |
| A | 01.02.2015 | 3 |
| A | 01.03.2015 | 4 |
| B | 01.01.2015 | 3 |
| B | 01.02.2015 | 4 |
| B | 01.03.2015 | 5 |
| C | 01.01.2015 | 1 |
| C | 01.02.2015 | 2 |
| C | 01.03.2015 | 3 |
+------+------------+---------------------------------+
There is no unique constraint or PK defined.
The table represents a highscore of a game. Every day the score of all players are inserted with values that are: name, points, now(),...
The data represent a snapshot of the score of each player at a specific time.
I want the most recent entry for each user only but only for the highest X players. So the result should look like
+------+------------+---------------------------------+
| name | date | score |
+------+------------+---------------------------------+
| A | 01.03.2015 | 4 |
| B | 01.03.2015 | 5 |
+------+------------+---------------------------------+
C doesn't appear since he's not in the top 2 (by score)
A appears with the most recent row (by date)
B appears, like A, with the most recent row (by date) and because he is in the top 2
I hope it becomes clear what I mean.
Thanks in advance!
I understand that what you need is to first select the X players who've gotten the highest score and then get their latest performance. In this case, you should do this:
SELECT *
FROM tablename t
JOIN
(
SELECT t.name, max(t.date) as max_date
FROM tablename t
JOIN
(
SELECT name
FROM
(
SELECT name, max(score) as max_score
FROM table_name
GROUP BY name
) all_highscores
ORDER BY max_score DESC
LIMIT X
) top_scores
ON top_scores.name = t.name
GROUP BY t.name
) top_last
on t.name = top_last.name
and t.date = top_last.date;

Mysql include column with no rows returned for specific dates

I would like to ask a quick question regarding a mysql query.
I have a table named trans :
+----+---------------------+------+-------+----------+----------+
| ID | Date | User | PCNum | Customer | trans_In |
+----+---------------------+------+-------+----------+----------+
| 8 | 2013-01-23 16:24:10 | test | PC2 | George | 10 |
| 9 | 2013-01-23 16:27:22 | test | PC2 | Nick | 0 |
| 10 | 2013-01-24 16:28:48 | test | PC2 | Ted | 10 |
| 11 | 2013-01-25 16:36:40 | test | PC2 | Danny | 10 |
+----+---------------------+------+-------+----------+----------+
and another named customers :
+----+---------+-----------+
| ID | Name | Surname |
+----+---------+-----------+
| 1 | George | |
| 2 | Nick | |
| 3 | Ted | |
| 4 | Danny | |
| 5 | Alex | |
| 6 | Mike | |
.
.
.
.
+----+---------+-----------+
I want to view the sum of trans_in column for specific customers in a date range BUT ALSO include in the result set, those customers that haven't got any records in the selected date range. Their sum of trans_in could appear as NULL or 0 it doesn't matter...
I have the following query :
SELECT
`Date`,
Customer,
SUM(trans_in) AS 'input'
FROM trans
WHERE Customer IN('George','Nick','Ted','Danny')
AND `Date` >= '2013-01-24'
GROUP BY Customer
ORDER BY input DESC;
But this will only return the sum for 'Ted' and 'Danny' because they only have transactions after the 24th of January...
How can i include all the customers that are inside the WHERE IN (...) function, even those who have no transactions in the selected date range??
I suppose i'll have to join them somehow with the customers table but i cannot figure out how.
Thanks in advance!!
:)
In order to include all records from one table without matching records in another, you have to use a LEFT JOIN.
SELECT
t.`Date`,
c.name,
SUM(t.trans_in) AS 'input'
FROM customers c LEFT JOIN trans t ON (c.name = t.Customer AND t.`Date` >= '2013-01-24')
WHERE c.name IN('George','Nick','Ted','Danny')
GROUP BY c.name
ORDER BY input DESC;
Of course, I would mention that you should be referencing customer by ID, and not by name in your related table. Your current setup leads to information duplication. If the customer changes their name, you now have to update all related records in the trans table instead of just in the customer table.
try this
SELECT
`Date`,
Customer,
SUM(trans_in) AS 'input'
FROM trans
inner join customers
on customers.Name = trans.Customer
WHERE Customer IN('George','Nick','Ted','Danny')
GROUP BY Customer
ORDER BY input DESC;