mysql UNION with COUNT - mysql

I know there are many posts in similar issues to mine, but I do not seem to be able to find an applicable solution to my case, as below.
I have added null columns so that the number of columns match and I know that I need to have all columns stated in the first select. Therein lies the problem. I do not know how to include a COUNT column in the first select that would correspond to the COUNT in the second select.
Thanks for the assistance.
First select:
SELECT brands.brand_id,
brands.brand,
models.model_id,
models.model,
segments.segment_id,
segments.segment,
versions.version_id,
versions.version,
versions.places,
versions.gearbox,
versions.doors,
prices.price
FROM versions
INNER JOIN models USING (model_id)
INNER JOIN segments USING (segment_id)
INNER JOIN brands USING (brand_id)
INNER JOIN prices USING(version_id)
WHERE price BETWEEN 200001 AND 225000
AND brands.active = 'Y'
AND models.active = 'Y'
AND versions.active = 'Y'
Second select:
SELECT Count(*) AS SafetyItems,
version_id,
NULL AS COL3,
NULL AS ....,
NULL AS COL12
FROM versiontrim
INNER JOIN trims USING(trim_id)
INNER JOIN versions USING(version_id)
INNER JOIN prices USING(version_id)
INNER JOIN models USING (model_id)
INNER JOIN brands USING (brand_id)
WHERE trimtype IN( 'sec', 'help' )
AND price BETWEEN 200001 AND 225000
AND brands.active = 'Y'
AND models.active = 'Y'
AND versions.active = 'Y'
GROUP BY version_id
Sample result of first select:
brand_id brand model_id model segment_id version_id price
58 Renault 11 Megane 4 44 209900
58 Renault 14 Scenic 5 54 209900
58 Renault 11 Megane 4 69 200900
71 Toyota 29 Yaris 2 214 200900
71 Toyota 30 Auri 4 216 207900
52 Nissan 58 Pick-up 14 282 209000
24 Ford 21 Focus 4 290 209000
Sample result of second select that I want have appended to above ( after the price column):
SafetyItems version_id
9 44
7 54
9 69
10 214
6 216
1 282
10 290

I guess you also want to put a NULL column in your first SELECT statement that would correspond for the COUNT column in the second SELECT statement.
Just put a NULL column in your first SELECT just like in your second SELECT statement, that should be fine. And do not forget the ALIAS of the column, since UNION uses the column name of the first SELECT.
SELECT
NULL AS SafetyItems,
brands.brand_id,
brands.brand,
models.model_id,
models.model,
segments.segment_id,
segments.segment,
versions.version_id,
versions.version,
versions.places,
versions.gearbox,
versions.doors,
prices.price
FROM versions
INNER JOIN models
USING (model_id)
INNER JOIN segments
USING (segment_id)
INNER JOIN brands
USING (brand_id)
INNER JOIN prices
USING(version_id)
WHERE price BETWEEN 200001 AND 225000
AND brands.active='Y'
AND models.active='Y'
AND versions.active='Y'
But then, you need to add another NULL column in the second SELECT to match with column count in the first SELECT. Hope this will help you.

I realized I was going about this with the wrong approach. Initially I thought I could not do select 2 with COUNT as part of select 1. It turns out it is possible and I managed to have it done after some struggling.
Thanks for the input. Please see solution below:
SELECT brands.brand_id,
brands.brand,
models.model_id,
models.model,
segments.segment_id,
segments.segment,
versions.version_id,
versions.version,
versions.places,
versions.gearbox,
versions.doors,
prices.price,
COUNT(trimtype)
FROM versions
INNER JOIN models USING (model_id)
INNER JOIN segments USING (segment_id)
INNER JOIN brands USING (brand_id)
INNER JOIN prices USING(version_id)
INNER JOIN versiontrim USING(version_id)
INNER JOIN trims USING(trim_id)
WHERE price BETWEEN 200001 AND 210000
AND trimtype IN('sec', 'help')
AND brands.active = 'Y'
AND models.active = 'Y'
AND versions.active = 'Y'
GROUP BY version_id

Related

MySQL Show results where not all conditions are met

I have three tables
Table A (orders)
order_number order_id
9999 123
Table B (order_items)
order_id product_id price
123 111 10
123 112 11
123 113 12
123 114 13
and Table C (product_customfields)
product_id customfield_id customfield_value
111 10 A
112 10 A
113 10 B
113 9 xyz
As a result I would like to get the product_id the price and in case a product has the customfield_id = 10 also the customfield_value
So in this case as a result I expect:
product_id price customfield_value
111 10 A
112 11 A
113 12 B
114 13 (empty)
In general my query looks like the following:
select B.product_id, B.price, C.customfield_value from orders A
left join order_items B on A.order_id=B.order_id
left join product_customfields C on B.product_id=C.product_id where A.order_number=9999 and C.customfield_id = 10
Of course the result will not show the product_id 114 because it has no customfield_id assigned in the database table with a value of "10"
Nevertheless could someone point me in the right direction how to build the query in a way to also show all products of the orders also if they are not assigned to a condition in the table.
Thank you
Does
select B.product_id, B.price, C.customfield_value from orders A
left join order_items B on A.order_id=B.order_id
left join product_customfields C on B.product_id=C.product_id
where A.order_number=9999 and (C.customfield_id = 10 or C.customfield_id IS NULL)
solves your issue?
You need a left outer join on the product_custom_fields like this
select B.product_id, B.price, C.customfield_value
from orders A
left join order_items B
on A.order_id=B.order_id
left outer join product_customfields C
on B.product_id=C.product_id
where A.order_number=9999 and
(C.customfield_id = 10 or C.customfield_id IS NULL)

want to ignore duplicate raws on group result

Result Right Now , want to ignore dulicate
id_category name id_manufacturer name
6 CLOTH of House 12 Sabb
6 CLOTH of House 12 Sabb
6 CLOTH of House 14 CTES
8 Sabih Nopoe 12 Sabb
I want this Result remove duplicate and heading changes
id_category Man-name id_manufacturer Cat-name
6 CLOTH of House 12 Sabb
6 CLOTH of House 14 CTES
8 Sabih Nopoe 12 Sabb
SELECT
p.id_category_default,
c.name,
p.id_manufacturer,
d.name
FROM
psup_product p
INNER JOIN psup_manufacturer d ON
p.id_manufacturer = d.id_manufacturer
INNER JOIN psup_category_lang c ON
p.id_category_default = c.id_category
WHERE p.id_category_default > 2
GROUP BY p.id_product
ORDER BY p.id_category_default
Your code show you're working on PrestaShop table
this code will work please check
SELECT
p.id_category_default,
c.name as Man-name,
p.id_manufacturer,
d.name as Cat-name
FROM
psup_product p
INNER JOIN psup_manufacturer d ON
p.id_manufacturer = d.id_manufacturer
INNER JOIN psup_category_lang c ON
p.id_category_default = c.id_category
WHERE p.id_category_default > 2
GROUP BY d.id_manufacturer
ORDER BY c.id_category
You can remove duplicates by selecting DISTINCT values or by GROUPing. DISTINCT will return only distinct values across all the columns you selected. GROUPing will group rows into summary rows by the fields you group by.
Here either adding DISTINCT after your SELECT statement, or including all the fields in your SELECT statement in your GROUP BY statement should return distinct records. Because you grouped by id_product which is not in the SELECT statement, it will not remove duplicates.
Examples in code would be:
Updating SELECT statement to include DISTINCT
SELECT DISTINCT --Adding DISTINCT keyword
p.id_category_default,
or, updating GROUP BY statement to include all fields in the SELECT statement.
GROUP BY --Removed p.id_product from the grouping and added fields from SELECT statement.
p.id_category_default,
c.name,
p.id_manufacturer,
d.name

SUM specific column using group by and how to avoid least joining table values from that?

i have query select of 3 tables using left joins by that i want sum of second table column value but by adding third table join we get some extra column on summing second table column value i need to avoid this
here explanation,
indents(table 1)
indent_no | indent_name | request_qty
1131 AAA 834
purchase_order(table 2)
pur_id | pur_qty | indent_no
121 34 1131
122 100 1131
123 10 1131
grn (table 3)
grn_no | grn_val | pur_id
1 34 121
2 23 121
3 21 122
my query to get sum(purchase_order.pur_qty) it should be 144 right
but i am getting 178 because the grn table contains 2 rows for pur_id(121)
pls note i can only allowed to use group by clause for indents.indent_no
only
i tried to get 144 but getting 178 ... see you can get actual result if you use group by purchase_order.pur_id and with the select of sum(purchase_order.pur_qty)/count(grn.pur_id) but i cant use group by column other than indents.indent_no
select sum(purchase_order.pur_qty) from indents
left join purchase_order on purchase_order.indent_no = indents.indent_no
left join grn on grn.pur_id = purchase_order.pur_id
group by indents.indent_no
i want the result
indent_no sum(purchase_order.pur_qty) SUM(grn_val)
1131 144 78
Try this query,
select indents.indent_no,sum(DISTINCT(purchase_order.pur_qty)),sum(grn.grn_val) from indents
left join purchase_order on purchase_order.indent_no = indents.indent_no
left join grn on grn.pur_id = purchase_order.pur_id
group by indents.indent_no
You can try below - you don't need to join with grn table as you only want to sum of purchage qty
select indents.indent_no,sum(purchase_order.pur_qty) from indents
left join purchase_order on purchase_order.indent_no = indents.indent_no
group by indents.indent_no
In case you need to join with grn table then you can do this using subquery of grn table -
You can see that grn table has multiple value of one purchase id and that's reason of duplication and you get wrong result from your current query
select indents.indent_no,sum(purchase_order.pur_qty) from indents
left join purchase_order on purchase_order.indent_no = indents.indent_no
left join (select pur_id, sum(grn_va) as gval from grn group by pur_id) as grn
on grn.pur_id = purchase_order.pur_id
group by indents.indent_no

JOIN vs "just" SELECT

I have the next tables:
date Income AccIncome
--------------------------------
2016-10-1 10 10
2017-11-1 20 30
date Qty AccQty
--------------------------------
2016-10-1 2 2
2017-11-1 4 6
date Ava AccAva
--------------------------------
2016-10-1 3 3
2017-11-1 4 7
I need to obtain:
date Income AccIncome Qty AccQty Ava AccAva
------------------------------------------------------
2016-10-1 10 10 2 2 3 3
2017-11-1 20 30 4 6 4 7
I could use a select using all these tables but how could this be done with a JOIN? Could the JOIN be much faster than using just a SELECT over all these tables picking up just the fields I need?
You can use inner join on date if the joining values in rows always match
select a.date, a.income, a.AccIncome, b.Qty, b.AccQty, c.Ava, c.AccAva
from table1 a
inner join table2 b on a.date= b.date
inner join table3 c on a.date = c.date
or left join if can not match
select a.date, a.income, a.AccIncome, b.Qty, b.AccQty, c.Ava, c.AccAva
from table1 a
left join table2 b on a.date= b.date
left join table3 c on a.date = c.date
if you use only a select withou join and on condtion you obtain a cartesia product of all the rows .. so in your case instead of two row as result .. you get 8 rows
and the inner/left join is normally much more faster that a cross join ( a select over all table) because work on reduced set o rows.. for help the join performance is useful a proper indexinig of the rows
the on clause in join and the same condition in where clause do the same work .. is only a diffrent sintax in the first case you have an explict join sintax more clear to read in the secondo you have an inplicit join .

MySQL - Selecting data from three different tables

I'm trying to select data from three different tables. How would I go about joining these tables to make the proper query?
****customers****
--------------------------
id full_name
54 Matt Damon
53 Jimmy Kimmel
****samples****
--------------------------
id rma_id
57 USARP011315-25
56 USARP011315-24
****early_ships****
--------------------------
customer_id sample_id shipping_carrier
54 57 UPS
53 56 FedEx
This is the query I've been running but I've yielded 0 results. This is the tutorial I've been following: http://javarevisited.blogspot.com/2012/11/how-to-join-three-tables-in-sql-query-mysql-sqlserver.html
SELECT samples.rma_id, customers.full_name, early_ships.shipping_carrier,
FROM customers c JOIN early_ships e ON c.id = e.customer_id
JOIN samples s ON e.sample_id = s.id
You have to use the table aliases in the SELECT clause. Please check this fiddle I created for you. It's working perfectly. http://sqlfiddle.com/#!2/49462/8
Two issues:
There's an extra comma at the end of the SELECT clause.
In the FROM..JOIN clause, you've given nicknames, but then you're trying to use the original names in the SELECT clause.
Try this:
SELECT s.rma_id, c.full_name, e.shipping_carrier
FROM customers c
JOIN early_ships e
ON c.id = e.customer_id
JOIN samples s
ON e.sample_id = s.id
(whitespace added for readability)