I have two mySQL tables as follows:
[product] table
P_id | Name | Quantity
1 | B | 10
2 | C | 15
3 | A | 8
[attribute] table
P_id | Name | Quantity
1 | Black | 5
1 | Red | 5
2 | Blue | 6
2 | Black | 9
How can I write an SQL query so that it can show the result from the above two tables as follows:
Report:
P_id | Name | Quantity
3 | A | 8
1 | B | 10
1 | Black | 5
1 | Red | 5
2 | C | 15
2 | Black | 9
2 | Blue | 6
These should be sorted on [Name] column, but these should be grouping on P_id column as above. By "grouping" on P_id, I mean "keeping all records with the same P_id next to each other". IS it possible to retrieve as above arrangement using a single SQL query.
SELECT P_id, Name, Quantity FROM (
SELECT P_id, Name, Quantity, Name as parent, 1 as level
FROM product
UNION
SELECT a.P_id, a.Name, a.Quantity, p.Name as parent, 2 as level
FROM attribute a JOIN product p ON a.P_id = p.P_id
) combined ORDER BY parent, level, Name
It should be Union operation, I believe like this:
select * from product union select * from attribute order Name;
Not sure why you wrote you need `group by' since your output is not grouped by any column.
Do you mean that you just need an union of both tables?
You can try this:
Select P_id, Name, Quantity
From product
Union
Select P_id, Name, Quantity
From attribute
Order by 2
SELECT * FROM
(
SELECT P_id, Name , Quantity FROM product
UNION ALL
SELECT P_id, Name , Quantity FROM attribute
) Order by Name
You will have to use grouping my friend. Then you can order on Both of you required columns like this:
SELECT * FROM product UNION SELECT * FROM attribute ORDER BY Name, P_id;
If you want them ordered by P_id and then Name, this should work.
(SELECT P_id, Name, Quantity FROM product)
UNION
(SELECT P_id, Name, Quantity FROM attribute)
ORDER BY P_id, Name;
Related
I want to get the last activity of my client but i dont know how to that that with two tables that have more than one pivot. Please look at to the example below :
table product
--------------------------------------------------------------------------------------------------------------------------------------
id | name | check_mo (Activity1) | check_mo_account_id | check_pa (Activity2) | check_pa_account_id
--------------------------------------------------------------------------------------------------------------------------------------------
1 | product1 | 01/02/2020 | 63 | 05/02/2020 | 100
2 | product2 | 01/03/2020 | 23 | 10/03/2020 | 63
-----------------------------------------------------------------------------------------------------------------------------------
Table account
--------------------------------
id | name
--------------------------------
23 | name1
63 | name2
100 | name3
--------------------------------
I want this result (last activity is the lastest date of (check_mo and check_pa). and relationship between tables is (account.id => product.check_mo_account_id and product.check_pa_account_id))
------------------------------------------------
id | name | last activity
-------------------------------------------------
23 | name1 | 01/03/2020
63 | name2 | 10/03/2020
100 | name3 | 05/02/2020
-------------------------------------------------
Unpivot the columns. In MySQL, you can use union all. Use join to bring in the names and then a window function to get the most recent date:
select pn.*
from (select pn.*, max(dte) over (partition by name) as max_dte
from ((select n.name, p.check_mo as dte, p.check_mo_account_id as account_id
from product p join
name n
on p.check_mo_account_id = n.id
) union all
(select n.name, p.check_pa, p.check_pa_account_id as account_id, p.check_pa
from product p join
name n
on p.check_mo_account_id = n.id
)
) pn
) pn
where dte = max_dte;
If I understand correctly, you have two check IDs and two check dates in one row, but want to treat them equally, just as if you had just one table with one check ID and one check date per row. Use UNION ALL to get this table. Then find the maximum date per ID and join this to the account table.
select id, account.name, aggregated.last_activity
from account
join
(
select id, max(check) as last_activity
from
(
select check_mo_account_id as id, check_mo as check from product
union all
select check_pa_account_id as id, check_pa as check from product
) unioned
group by id
) aggregated using (id)
order by id;
I'm trying to select SUMed data from two tables.
This is how they look.
Table1:
products | revenue|
------------------|
product1 | 10 |
product2 | 20 |
product1 | 20 |
Table2:
products | revenue|
------------------|
product1 | 40 |
product2 | 30 |
product2 | 40 |
So the query should sum them like this:
products | revenue|
------------------|
product1 | 70 |
product2 | 90 |
I've tried this and some other queries but they are incorrect.
SELECT Table1.products, Table1.SUM(`revenue`), Table2.SUM(`revenue`)
FROM Table1
JOIN Table2
ON Table1.products = Table2.products
group by Table1.products;
Could you help me, what is the right query in this case? Thanks.
I would recommend using union all and then group by:
select product, sum(revenue)
from ((select product, revenue from table1) union all
(select product, revenue from table2)
) tt
group by product;
This will ensure that all products are in the result set, even products that are only in one table.
Use UNION ALL and SUM aggregate function :
SELECT products , SUM(revenue) revenue
FROM
(
SELECT products , revenue
FROM table1
UNION ALL
SELECT products , revenue
FROM table2
) A
GROUP BY products
I have the below 2 MYSQL weekly tables:
TableA_Wk1
Id | Price
----------
1 | 1
1 | 2
2 | 5
TableA_Wk2
Id | Price
----------
1 | 2
4 | 2
I can group the price in one table:
SELECT Id, SUM(Price) FROM TableA_Wk1
GROUP BY Id
and get
Id | Price
----------
1 | 3
2 | 5
I would like to also consider the table TableA_Wk2 to get the below:
Id | Price
----------
1 | 5
2 | 5
4 | 2
If i use UNION ALL the result is separated:
SELECT Id, SUM(Price) FROM TableA_Wk1
GROUP BY Id
UNION ALL
SELECT Id, SUM(Price) FROM TableA_Wk2
GROUP BY Id
First get all the <Id,price> tuples from those two tables. Then Use SUM and GROUP BY Id on the resultant table.
SELECT
t.Id,
SUM(t.price)
FROM
(
SELECT Id, Price FROM TableA_Wk1
UNION ALL
SELECT Id, Price FROM TableA_Wk2
) AS t
GROUP BY t.Id
Note
UNION removes duplicates.
UNION ALL doesn't.
First UNION , then GROUP BY :
SELECT t.id,sum(t.price) as price
FROM (
SELECT id,price from TableA_Wk1
UNION ALL
SELECT id,price from TableA_Wk2
) t
GROUP BY t.id
Union the result set and then perform summation to get the summed value.
select sum(price) from (
select price from TableA_Wk1
union all
select price from TableA_Wk1
) as alais
I have a data structure in the table of these columns
ID | Title | Category_level_1 | Category_level_2 | Category_level_3
1 | offer 1 | Browns | Greens | White
2 | offer 1 | Browns | White |
3 | offer 2 | Greens | Yellow |
4 | offer 3 | Browns | Greens |
5 | offer 4 | Browns | Yellow | White
Without the ability to change the table structure I need to "count the number for Offers per Category across the 3 columns"
There is also columns for date range of the offer, to limit to the current ones, but I want to work out the query first.
I need to get a list of all the Categories and then put offers against them.
Offer can be in the table more than once.
As far as I have got is do a temp table first with a UNION.
CREATE TEMPORARY TABLE IF NOT EXISTS Cats AS
( SELECT DISTINCT(opt) FROM (
SELECT Category_level_1 AS opt FROM a_table
UNION
SELECT Category_level_2 AS opt FROM a_table
UNION
SELECT Category_level_3 AS opt FROM a_table
) AS Temp
) ;
SELECT
Cats.opt AS "Joint Cat",
(
SELECT count(*)
FROM a_table
WHERE a_table.`Category_level_1` = Cats.opt
OR a_table.`Category_level_2` = Cats.opt
OR a_table.`Category_level_3` = Cats.opt
GROUP BY a_table.Title
) As Total
FROM Cats
WHERE Category_level_1 != ''
ORDER BY Category_level_1 ASC;
ISSUE:
a) so the union works well and I get my values. DONE
b) the Total subselect though is not grouping correctly.
I just want a count of all the rows returned but it is grouping with a count of the row titles not all rows.
So trying to work out how to figure this should work and the SQL could be totally different with the answer:
Joint Category | Total Count of offers
Browns | 3
White | 3
Greens | 2
Yellow | 2
plan
take a union of all distinct categories, alias to Joint Category
aggregate count over Joint Category ( where not null or blank - not clear from your rendering if those fields are null or blank.. )
grouping by Joint Category
query
select `Joint Category`, count(*) as `Total Count of offers`
from
(
select Title, Category_level_1 as `Joint Category`
from a_table
union
select Title, Category_level_2
from a_table
union
select Title, Category_level_3
from a_table
) allcats
where `Joint Category` is not null
and `Joint Category` <> ''
group by `Joint Category`
;
output
+----------------+-----------------------+
| Joint Category | Total Count of offers |
+----------------+-----------------------+
| Browns | 3 |
| Greens | 3 |
| White | 2 |
| Yellow | 2 |
+----------------+-----------------------+
sqlfiddle
Your results are a bit confusing . . . I cannot tell why browns and whites both have a count of 3. I think you are counting the combination of level and category.
I would be inclined to approach this using union all and then use count() or count(distinct), depending on what the counting logic really is. For the combination of level and category:
SELECT cat, COUNT(DISTINCT level, title) as numtitles
FROM ((SELECT title, 1 as level, category_level1 as cat FROM a_table) union all
(SELECT title, 2 as level, category_level2 as cat FROM a_table) union all
(SELECT title, 3 as level, category_level3 as cat FROM a_table)
) tc
WHERE cat is not null
GROUP BY cat;
You can include the date column in each of the subqueries and then include a condition in the WHERE clause.
I have a typical products table with the fields name and price. I have to select the sum of all the prices, the name of the cheapest product and the name of the most expensive product and then return it all in the same result set. I've tried some combinations but the best I could come up with was an ugly query with multiple nested subselects. Can anyone help me with a good query example, please? Thanks in advance.
To illustrate the problem, here is a minimalistic products table:
+----+-------+------------------+
| id | price | name |
+----+-------+------------------+
| 1 | 2.20 | Shack Beer |
| 2 | 3.40 | Freeze IPA |
| 3 | 1.10 | Poor Man's Ale |
| 4 | 3.40 | Alabama Sour |
| 5 | 7.20 | Irish Stout |
+----+-------+------------------+
Given the table above, the query must return the following result set:
total_pricing = 17.30
cheapest_product = Poor Man's Ale
most_expensive_product = Irish Stout
Here are a couple of options for you (SQL Fiddle):
SELECT SUM(p.price) AS total_pricing,
(
SELECT name
FROM products
ORDER BY price
LIMIT 1
)AS cheapest_product,
(
SELECT name
FROM products
ORDER BY price DESC
LIMIT 1
)AS most_expensive_product
FROM products p;
Or in separate rows:
SELECT 'total_pricing' as Category, SUM(p.price) AS total_pricing
FROM products p
UNION
(
SELECT 'cheapest_product', name
FROM products
ORDER BY price
LIMIT 1
)
UNION
(
SELECT 'most_expensive_product', name
FROM products
ORDER BY price DESC
LIMIT 1
);
Check SQL Fiddle
SELECT DISTINCT price,
name
FROM products AS p1,
(SELECT MAX(price) AS `most_expensive_product`,
MIN(price) AS `cheapest_product`
FROM products) AS p2
WHERE p2.most_expensive_product = p1.price
OR p2.cheapest_product = p1.price
UNION
SELECT sum(price) AS price,
"Total_pricing" AS name
FROM products;