complex sql query counting and grouping - mysql

in table LOG i have the following entries
userid item role
1 Apple Buyer
2 Banana Seller
3 Apple Buyer
1 Banana Seller
3 Orange Buyer
etc
i'm trying to create the following two tables with SQL. table 1:
item countUser1Buy countUser1Sell
Apple
Banana
Orange
AND TAble 2 (here i mean the mean of totals. as in, the mean of the total apples bought
item alluserBuyTotalMean allUserBuyTotalMedian allUserBuyRange allUserBuyStandardDev
Apple
Banana
Orange
i think the first should be a variation on
`SELECT `item`, `role`, count(`item`) as count FROM `LOG` GROUP BY `item`
which is close, giving me
item role count
Apple Buyer 1
Banana Seller 1
but i cant figure out how to make it as i'm trying to get. the second i'm really stumped. thanks

You need conditional aggregation for this:
SELECT `item`,
COUNT(CASE WHEN role='Seller' THEN 1 END) AS countUserSell,
COUNT(CASE WHEN role='Buyer' THEN 1 END) AS countUserBuy
FROM `LOG`
GROUP BY `item`

First query:
SELECT item
, SUM(role = 'Buyer') AS countUser1Buy
, SUM(role = 'Seller') AS countUser1Sell
FROM LOG
WHERE userid = 1
GROUP BY item;
Second query:
SELECT item
, AVG(total) AS alluserBuyTotalMean
, CONCAT(MIN(total), ' - ', MAX(total)) AS allUserBuyRange
, STDDEV_POP(total) AS allUserBuyStandardDev
FROM (
SELECT item
, COUNT(*) AS total
FROM LOG
WHERE role = 'Buyer'
GROUP BY item, userid
) t
GROUP BY item;

SELECT
`item`
,SUM(CASE WHEN `userid`= 1 AND `role` = 'Buyer' THEN 1 ELSE 0 END) as countUser1Buy
,SUM(CASE WHEN `userid` = 1 AND `role` = 'Seller' THEN 1 ELSE 0 END) as countUser1Sell
FROM `LOG`
GROUP BY Item
You will need to make a new CASE statement for each userid, but this should work. Results in the following:
item countUser1Buy countUser1Sell
Apple 1 0
Banana 0 1
Orange 0 0

Related

Query about Items in one Table

I looking for a query which based on a table were I have all Items from my shops. This table contains the following columns:
location: Shop Name
product: Item Number
attributinstance_id: not in use so it always is NULL
Units:count of Items
I like to write a query where I can see which Items are in the other Shops and how much of them and the result should be in the same row.
For example:
Shop 1 Shop 2 Shop 3
item 1 1 2 5
I get it running with the items which are in all tree shops available or was available but when i look up items which were only available in one of the tree shops they will not showing. Has there anybody an idea?
My idea so far:
SELECT Distinct
products.name AS Artikel,
eins.units AS Europa_Center,
zwei.Units AS O_Strasse,
drei.units AS K_Strasse
FROM stockcurrent eins
LEFT JOIN stockcurrent zwei
ON (eins.product = zwei.product
AND eins.location ='0'
AND zwei.location ='a59cb899-27f4-460c-b5df-89a89eaaef75')
LEFT JOIN stockcurrent drei
ON (zwei.product = drei.product
AND zwei.location ='a59cb899-27f4-460c-b5df-89a89eaaef75'
AND drei.location ='3b53adf5-eaee-4a13-b22b-39d50b14e497')
JOIN products
ON products.id = eins.product
JOIN locations
ON locations.id = eins.location
The Whole think is for the POS System Unicentas 4.3. The Table look like this:
Location Product atributsinstance_id Units
shop_1 item_1 NULL 5
shop_2 item_1 NULL 1
shop_3 item_1 NULL 0
shop_2 item_2 Null 3
shop_1 item_3 Null 2
shop_2 item_3 Null 4
shop_3 item_3 Null 1
You need conditional aggregation:
SELECT product_id,
SUM(CASE WHEN location = 'SHOP1' THEN units ELSE 0 END) as shop_1,
SUM(CASE WHEN location = 'SHOP2' THEN units ELSE 0 END) as shop_2,
SUM(CASE WHEN location = 'SHOP3' THEN units ELSE 0 END) as shop_3
FROM stock
GROUP BY product_id

How display the count of associates at each rating?

I have a table called associate_ratings with the below structure:
id int(11) NO PRI auto_increment
associate varchar(10) NO
skill_id int(11) NO MUL
rating int(11) NO
updated_time datetime NO
This table holds the skills(skill_id) of the associate and their corresponding rating in that skill.
Rating column can take values (1,2,3)
I want to get the in each skill how many associates have got a particular rating, please find below output table structure:
Skill_id Rating1_count Rating2_count Rating3_count
Java 2 1 4
C# 3 2 2
This says in Java there are 2 associates with rating 1, 1 associates with rating 2 & 4 associates with rating 3
I tried the below query, but the output is not in the format I expect:
SELECT skill_id, rating, count(*) FROM associate_ratings a
WHERE updated_time = (
SELECT max(updated_time)
FROM skill_set.associate_ratings b
WHERE a.associate = b.associate
) GROUP BY a.skill_id, a.rating order by a.skill_id, a.rating;
Could you please let me know how to get the output in the format I want?
Use temporary table and case
SELECT skill_id, sum(rating_1), sum(rating_2), sum(rating_3)
FROM (
SELECT a.skill_id as skill_id,
case a.rating when '1' then 1 else 0 end as rating_1,
case a.rating when '2' then 1 else 0 end as rating_2,
case a.rating when '3' then 1 else 0 end as rating_3
FROM associate_ratings a
WHERE updated_time = (
SELECT max(updated_time)
FROM skill_set.associate_ratings b
WHERE a.associate = b.associate
) ) as t
GROUP BY skill_id
ORDER BY skill_id;
select Skill_id ,
count(case when rating = 1 then 1 else null end) as Rating1_count ,
count(case when rating = 2 then 1 else null end) as Rating2_count ,
count(case when rating = 3 then 1 else null end) as Rating3_count
from associate_ratings b
left join associate_ratings a
on b.Skill_id = a.Skill_id
group by Skill_id
That would be something like this:
SELECT
skill_id,
sum(IF(rating=1,1,0)) as Rating1_count,
sum(IF(rating=2,1,0)) as Rating2_count,
sum(IF(rating=3,1,0)) as Rating3_count
FROM associate_ratings
GROUP BY skill_id
ORDER BY skill_id;
I think it's the most simple solution possible here.

Joining Tables and Pivoting Data with MySQL

Objective 1:
Your sales data is stored in the Purchases table.
Your sales staff wants to see the sales data in a pivoted form, broken down by quarter.
If your Purchases table doesn't have sales data, create some. Be sure the data spans four quarters.
Next, write a query to pivot the data as follows:
Album Q1 Q2 Q3 Q4
OK Computer 2 5 3 7
Sea Change 8 6 2 1
Do not create a separate table or a view. Do not alter any tables.
Save your query as dba1lesson10project1.sql and hand in the project.
This is What I need to do. But, the table it wants me to work with looks like this. And it states in the assignment I cannot alter it at all.
CustomerID DateOfPurchase SongID
1 2007-03-31 3
3 2007-06-30 4
4 2007-09-30 4
5 2007-12-31 5
I know I need to join three tables together so I can group by the title. Which are my Songs, Albums, and Purchases tables.
SELECT Albums.Title FROM Albums
LEFT JOIN Songs
INNER JOIN Purchases
ON Songs.SongID = Purchases.SongID
ON Albums.Title = Purchases.SongID,
SELECT Title,
SUM(CASE WHEN QUARTER(DateOfPurchase) = 1 THEN 1 ELSE 0 END) AS 'Q1',
SUM(CASE WHEN QUARTER(DateOfPurchase) = 2 THEN 1 ELSE 0 END) AS 'Q2',
SUM(CASE WHEN QUARTER(DateOfPurchase) = 3 THEN 1 ELSE 0 END) AS 'Q3',
SUM(CASE WHEN QUARTER(DateOfPurchase) = 4 THEN 1 ELSE 0 END) AS 'Q4'
From Purchases
GROUP BY Title;
I'm kind of at a loss here when it comes to Joining three separate tables then pivoting the data
I've tried the code above in multiple other variants which has failed me past the table joining portion.
Any help would be much appreciated.
My suggestion before attempting to PIVOT the data would be to first, write the query to return the columns that you need, this will involve joining your tables. You didn't provide your table definitions so I am making a few guesses on the structure. If your tables are structured similar to the following:
CREATE TABLE Purchases
(`CustomerID` int, `DateOfPurchase` datetime, `SongID` int)
;
CREATE TABLE Albums
(`AlbumId` int, `Title` varchar(11))
;
CREATE TABLE Songs
(`SongID` int, `AlbumID` int)
;
Then you would SELECT from the tables using a JOIN similar to this code:
select a.title,
p.DateOfPurchase
from albums a
inner join songs s
on a.albumid = s.albumId
inner join purchases p
on s.songid = p.songid
This query will return to you the album Title as well as the DateOfPurchase which you need to pivot the data. Once you have the JOINS worked out, then you can replace the p.DateOfPurchase with your aggregate function and CASE expression and add the GROUP BY clause to get the final result:
select a.title,
SUM(CASE WHEN Quarter(p.DateOfPurchase) = 1 THEN 1 ElSE 0 END) AS Q1,
SUM(CASE WHEN Quarter(p.DateOfPurchase) = 2 THEN 1 ELSE 0 END) AS Q2,
SUM(CASE WHEN Quarter(p.DateOfPurchase) = 3 THEN 1 ELSE 0 END) AS Q3,
SUM(CASE WHEN Quarter(p.DateOfPurchase) = 4 THEN 1 ELSE 0 END) AS Q4
from albums a
inner join songs s
on a.albumid = s.albumId
inner join purchases p
on s.songid = p.songid
group by a.title;
See SQL Fiddle with Demo. This gives a result:
| TITLE | Q1 | Q2 | Q3 | Q4 |
| OK Computer | 1 | 0 | 0 | 0 |
| Sea Change | 0 | 1 | 1 | 0 |

Join tables and get the same column to more columns based on the value

Lets say I join two tables and get a result like
id vendor vendor_id quantity
1 Sony 1 25
1 Apple 2 12
1 HTC 3 5
And I want the result to be like
id Quantity_Sony Quantity_Apple Quantity_HTC
1 25 12 5
How can I do that, I use Left joins to join the tables. I use mySql
SELECT ID,
MAX(CASE WHEN vendor = 'Sony' THEN Quantity END) Quantity_Sony,
MAX(CASE WHEN vendor = 'Apple' THEN Quantity END) Quantity_Apple,
MAX(CASE WHEN vendor = 'HTC' THEN Quantity END) Quantity_ATC
FROM
(
-- add your existing query here
) x
GROUP BY ID

COUNT from single column and seperate it into 2 column

This is my table "rating" in my database.
attraction customer rate
------------------------------------
attrac1 cust1 like
attrac2 cust1 dislike
attrac1 cust2 like
What SQL should i write to make the output become like this
attraction like dislike
----------------------------------
attrac1 2 0
attrac2 0 1
I tried this
SELECT a_id,
(SELECT COUNT(rate) FROM rating WHERE rate = 'like') as 'Like',
(SELECT COUNT(rate) FROM rating WHERE rate = 'dislike') as 'Dislike'
FROM rating
But I cant get the result that I want.
SELECT Attraction,
COUNT(CASE WHEN Rate = 'Like' THEN Customer END) [Like],
COUNT(CASE WHEN Rate = 'DisLike' THEN Customer END) [DisLike]
FROM Rating
GROUP BY Attraction
This is one approach:
SELECT a_id,
SUM(Case when rate='like' then 1 else 0 end) as 'Like',
SUM(Case when rate='dislike' then 1 else 0 end) as 'Dislike'
FROM rating
Group BY A_id