count for different column in union and displaying in same row - mysql

I am trying to get a count(*) for different column from a different table using union.
//tbl_churidar
order_id order_no_first order_no
--------------------------------------
1 C 1000
2 C 1001
3 C 1002
//tbl_anarkali
order_id order_no_first order_no
--------------------------------------
1 A 1003
2 A 1004
3 A 1005
//tbl_assign
assign_id order_id order_no_first
---------------------------------------
1 1 C
2 1 A
3 2 C
4 3 C
5 2 A
6 3 A
//tbl_unit_status
status_id assign_id status_status stitching_worker
-----------------------------------------------------------
1 1 Stitch AA
2 2 QC {null}
3 3 Stitch BB
4 4 Stitch BB
5 5 Stitch AA
6 6 Stitch CC
from the table tbl_unit_status where status_status = Stitch should INNER JOIN with other two table and get the total count of churidar and anarkali each stitching_worker taken.
the required output is,
churidar anarkali stitching_worker
----------------------------------------
1 1 AA
2 0 BB
0 1 CC
I have tried to get the above output but got stuck. Below is my code,
SELECT churidar, anarkali, stitching_worker
FROM ((
SELECT count(*) AS churidar, NULL AS anarkali,
us.stitching_worker
FROM tbl_unit_status us
INNER JOIN tbl_assign a ON a.assign_id = us.assign_id
INNER JOIN tbl_churidar o ON
(o.order_id = a.order_id AND
o.order_no_first = a.order_no_first)
INNER JOIN tbl_contacts c ON c.contacts_id = o.contacts_id
LEFT JOIN tbl_title t ON t.title_id = c.title_id
WHERE us.status_status = "Stitch" AND
o.order_no_first = "C"
GROUP BY us.stitching_worker
)
UNION (
SELECT NULL AS churidar, count(*) AS anarkali,
us.stitching_worker
FROM tbl_unit_status us
INNER JOIN tbl_assign a ON a.assign_id = us.assign_id
INNER JOIN tbl_anarkali o ON (
o.order_id = a.order_id AND
o.order_no_first = a.order_no_first)
INNER JOIN tbl_contacts c ON c.contacts_id = o.contacts_id
LEFT JOIN tbl_title t ON t.title_id = c.title_id
WHERE us.status_status = "Stitch" AND
o.order_no_first = "A"
GROUP BY us.stitching_worker
)
) AS T1
the output for the above code is,
churidar anarkali stitching_worker
----------------------------------------
1 0 AA
{null} 1 AA
2 0 BB
0 1 CC
how to get the required output. I have tried a lot. Help me find the answer. Thankyou.

If I understand correctly (which I may not), you don't need the first two tables. You can get the information you need from tbl_assign and just use aggregation:
select us.stitching_working,
sum(a.order_no_first = 'C') as churidar,
sum(a.order_no_first = 'A') as anarkali
from tbl_unit_status us join
tbl_assign a
on us.assign_id = a.assign_id
where us.status_status = 'Stitch'
group by us.stitching_working;

Related

Issue getting while fetching data using joins

I have four table and structure as below :
1)Budget
id Budget_name
1 test1
2 test2
3 test3
2)Yearly Budget
id amount_yearly budgetid
1 1000 1
2 2000 2
3 5000 3
ri_spent
id Spent_amount budgetid
1 100 2
2 100 2
3 200 3
4)FI_spent
id Spent_amount budgetid
1 100 2
2 100 3
3 200 3
i want to fetch data accourding to or based on first budget table id
below is the query i was trying:
select d.centers as Cost_Center,
ud.BUDGET_ANNUAL_AMOUNT as Annual_Budget,
l.LEAD_ID as Lead_Id,
l.AMOUNT as Lead_Amount,
f.FINANCEADD_ID as Finance_Id,
f.AMOUNT as Finance_Amount
from Cost_centers as d
inner join ANNUAL_BUDGET_BUDGET_CENTER as ud on d.id = ud.BUDGET_ID
inner join RI_DETAILS as l on l.COST_CENTER = d.id
inner join F_RI_DETAILS as f on f.COST_CENTER = d.id
ORDER BY d.id DESC
I want output of the following way:
Id Name ri_id FI_ID RI_Spent_Amount FI_Spent_Amount Annual_Buget
1 test1 1000
2 test2 1 1 100 200 1000
2 test2 2 100 2000
3 test3 3 2 300 100 2000
3 test3 3 200 2000
Any way if possible then please help me.
I want to minus annual budget with spent_amount later.
If possible then help me .
Please Try This Query ,
select b.id ,
b.Budget_name,
y.id,
y.amount_yearly,
r.id,
r.ri_spent,
f.id,
f.Spent_amount
from Budget b
INNER JOIN Yearly_Budget y on y.budgetid =b.id
INNER JOIN ri_spent r on r.budgetid =b.id
INNER JOIN FI_spent f on f.budgetid =b.id
ORDER BY b.id DESC
Could you please use left join instead of inner join. Requirement and sql arent matching so i may be little off. But you can get the idea.
select d.centers as Cost_Center,
ud.BUDGET_ANNUAL_AMOUNT as Annual_Budget,
l.LEAD_ID as Lead_Id,
l.AMOUNT as Lead_Amount,
f.FINANCEADD_ID as Finance_Id,
f.AMOUNT as Finance_Amount
from Cost_centers as d -- I assume this is the budget table
left outer join ANNUAL_BUDGET_BUDGET_CENTER as ud on d.id = ud.BUDGET_ID
left outer join RI_DETAILS as l on l.COST_CENTER = d.id
left outer join
(select sum(FINANCEADD_ID) FINANCEADD_ID,sum(AMOUNT) AMOUNT,id from
F_RI_DETAILS group by id) as f
on f.COST_CENTER = l.id
ORDER BY d.id DESC

SQL left join not getting result as expected

I have two tables as follows:
tableA
pat_id name user_id
1 sam 1
2 jose 1
3 sandra 2
tableB
id pat_id pat-main_name
1 1 MR0001
2 3 MR0005
I am expecting the result as follows:
pat_id name user_id pat-main_name
1 sam 1 MR0001
2 jose 1
I have user_id = 1
What I did is as follows:
SELECT tableA.pat_id,tableA.name,tableA.user_id,tableB.pat-main_name
FROM tableA
LEFT OUTER JOIN tableB
where tableA.pat_id = tableB.pat_id AND tableA.user_id;
and I am getting result as:
pat_id name user_id pat-main_name
1 sam 1 MR0001
2 jose 1
3 Sandra 2
What should I do?
This query properly joins the 2 tables:
SELECT tableA.pat_id
,tableA.name
,tableA.user_id
,tableB.`pat-main_name`
FROM tableA
LEFT OUTER JOIN tableB
ON tableA.pat_id = tableB.pat_id;
Your original query was sort of mixing the old syntax and the newer ANSI syntax which should be preferred:
old syntax = FROM a, b WHERE a.x = b.x...
new ANSI = ... JOIN ON a.x = b.x...
You can restrict the output by adding a WHERE clause such as WHERE tableA.user_id = 1 .
It will give this output:
1 sam 1 MR0001
2 jose 1
3 Sandra 2 NULL
Or with a WHERE clause tableA.user_id = 1:
1 sam 1 MR0001
2 jose 1
Use left join
SELECT tableA.pat_id,tableA.name,tableA.user_id,tableB.pat-main_name
FROM tableB left join tableA
ON tableB.pat_id = tableA.pat_id
WHERE tableA.user_id=1
This will work:
SELECT
tableA.pat_id, tableA.name, tableA.user_id,
tableB.`pat-main_name`
FROM tableA LEFT OUTER JOIN tableB ON tablea.pat_id = tableb.pat_id
Where tablea.user_id = 1
you can write query as follow:
SELECT `t`.`name`,
`t1`.`pat_id`,
`t1`.`pat-main_name`
FROM tableA AS t LEFT JOIN tableB AS t1 ON `t`.`pat_id` = `t1`.`pat_id`

Most sold products in shop transactions

I am trying to build a query to select the most sold products given the number of top products to fetch and the language code. I don't know to do it right so I would appreciate you help.
shop_transactions
id
1
2
3
shop_transaction_products_match
id | shop_transaction_id | product_id | units_bought
1 1 1 4
2 2 2 1
3 3 2 2
products_translations
id | product_id | language_code | name | seo_name
1 1 es Hola hola
2 1 en Hey u hey-u
3 2 es Adiós adios
4 2 en Bye u bye-u
products
id | category_id
1 1
2 2
product_categories
id
1
2
product_categories_translations
id | category_id | language_code | name | seo_name
1 1 es AA aa
2 1 en BB bb
3 2 es CC cc
4 3 en DD dd
The information per row is: name from product_translations, seo_name from product_translations, name from product_categories_translations, seo_name from product_categories_translations
Rows ordered descendant by number products sold in total.
Considering the example information, the result if number of products to fetch is 2 and the language is es, would be:
Hola, hola, AA, aa -> 4 units sold of this product
Adiós, adios, CC, cc -> 3 units sold of this product
Thank you!
Edit:
The code I tried so far... and I am missing some things that I dont know how to do it:
SELECT pt.name, pt.seo_name, pct.name as name_category, pct.seo_name as seo_name_category
From product_translations pt, products p, product_categories pc, product_categories_translations pct
where p.id in (Select product_id from shop_transaction_product_match where shop_transaction_id in
(Select id from shop_transactions)) AND pt.language_code = :language_code AND pct.language_code = :language_code
AND p.category_id = pct.category_id
Try this one:
SELECT DISTINCT
pt.name, pt.seo_name, pct.name, pct.seo_name,
SUM(stpm.units_bought) units_sold
FROM products AS p
LEFT JOIN product_categories AS pc ON p.category_id = pc.id
LEFT JOIN products_translations AS pt ON p.id = pt.product_id AND pt.language_code = 'es'
LEFT JOIN product_categories_translations AS pct ON pc.id = pct.category_id AND pct.language_code = 'es'
LEFT JOIN shop_transaction_products_match AS stpm ON p.id = stpm.product_id
-- Where p.id = 1
GROUP BY p.id
ORDER BY units_sold DESC
limit 2
Instead of using IN it is better to use INNER JOIN.
SELECT products_translations.name,
products_translations.seo_name,
product_categories_translations.name,
product_categories_translations.seo_name,
SUM(shop_transaction_products_match.units_bought) AS Product_count
FROM
shop_transactions
INNER JOIN
shop_transaction_products_match
ON shop_transactions.id=shop_transaction_products_match.shop_transaction_id
INNER JOIN
products_translations
ON products_translations.product_id = shop_transaction_products_match.product_id
INNER JOIN
products
ON products.id = shop_transaction_products_match.product_id
INNER JOIN
product_categories
ON products.category_id = product_categories.id
INNER JOIN
product_categories_translations
ON product_categories_translations.category_id = product_categories.id AND product_categories_translations.language_code = products_translations.language_code
WHERE products_translations.language_code= 'es' GROUP BY products.id
Limit 2
Hope this helps.

Why my right join isn't working?

I need to show all categories, even categories with no items.
I have this query.
SELECT
i.id,
incident_active 'Approved',
incident_verified 'Verified',
category_title 'Category',
ParentCategory 'Parent Category'
FROM
incident i
INNER JOIN
incident_category ic ON i.id = ic.incident_id
RIGHT JOIN
incident_person ip ON i.id = ip.incident_id
RIGHT JOIN
(SELECT
c1.id,
c1.parent_id,
c2.category_title ParentCategory,
CONCAT_WS(' -> ', c2.category_title, c1.category_title) category_title
FROM
category c1
left outer join category c2 ON c1.parent_id = c2.id WHERE c1.parent_id != 0) AS c ON c.id = ic.category_id
WHERE incident_dateadd > DATE_SUB(NOW(), INTERVAL 1 MONTH)
which return:
and this query:
SELECT
c1.id,
c1.parent_id,
c2.category_title ParentCategory,
CONCAT_WS(' -> ', c2.category_title, c1.category_title) category_title
FROM
category c1
left outer join category c2 ON c1.parent_id = c2.id WHERE c1.parent_id != 0
which return:
I've read several times this answer but I can not see why my right join isn't working.
The first result set should have 8 more columns, the columns of categories which parent is Protesta
UPDATE
I got it working whith the following query:
SELECT * FROM (SELECT
i.id,
incident_title 'Título',
incident_description 'Descripción',
incident_date 'Fecha',
incident_active 'Aprobado',
incident_verified 'Veficado',
person_first 'Nombres',
person_last 'Apellidos',
person_email 'Email',
category_id
-- category_title 'Categoría',
-- ParentCategory 'Categoría Padre'
FROM
incident i
INNER JOIN
incident_category ic ON i.id = ic.incident_id
RIGHT JOIN
incident_person ip ON i.id = ip.incident_id
WHERE (incident_dateadd > DATE_SUB(NOW(), INTERVAL 1 MONTH) OR incident_dateadd IS NULL)) a
RIGHT JOIN
(SELECT
c1.id,
c1.parent_id,
c2.category_title ParentCategory,
CONCAT_WS(' -> ', c2.category_title, c1.category_title) category_title
FROM
category c1
left outer join category c2 ON c1.parent_id = c2.id WHERE c1.parent_id != 0) b ON a.category_id = b.id
Although I still don't understand why it was not working with the first version, in my mind both queries are equivalent.
If anyone could explain the differences...
It's the location of your final where clause.
In your fist query, you pull all of your categories and associate them with a bunch of data, getting a compilation of rows. You then use a where clause to filter out many of those rows, some of which happen to be category rows.
Let's look at a simple example.
Table A:
X | Y
-----
1 | hi
2 | bye
3 | what
Table B:
Z | X
-----
A | 1
B | 1
C | 2
Given these tables, if I say the following
SELECT * FROM `B` RIGHT JOIN `A` ON A.X = B.X
my result will be:
Z | X | Y
---------
A | 1 | hi
B | 1 | hi
C | 2 | bye
- | 3 | what
If, however, I add a where clause on the end of that so my query becomes
SELECT * FROM `B` RIGHT JOIN `A` ON A.X = B.X WHERE B.Z > 'A'
some of table A is filtered out. Now I have:
Z | X | Y
---------
B | 1 | hi
C | 2 | bye
However, if my query does the filtering before the join, like so:
SELECT * FROM
(SELECT * FROM `B` WHERE B.Z > 'A') AS B
RIGHT JOIN `A` ON A.X = B.X
my table still contains all the rows from A.
Z | X | Y
---------
B | 1 | hi
C | 2 | bye
- | 3 | what
It's just a matter of order. In your original query, you select all the rows then filter out some. In your working query, you first filter, then you get all the category rows you need.

Getting an ID from 3 tables which has duplicate(multiple) keys and unique(single) key according to condition

I've tables like
places
uid place country
1 Kolkata 23
2 Walhaba 47
2 New York 4
3 Ariadaha 23
3 Mandirpur 23
3 Vala 23
perinfo
uid relation name hfor
1 1 ario 5
2 5 tina54 2
3 2 kiako2 2
likes
uid likeid
1 4
2 12
2 34
2 56
3 101
1 2
1 56
2 56
here u can see perinfo has uid as uniqueid but likes & places has a set of **uid**s
now i want to search for the uid who likes 34, lives in Walhaba and with hfor 2
(which is uid 2 int his example and could be many)
i've tried inner join but its showing duplicate(all) results for places and likes.
i just want single results for each match.
how to do it?
SELECT p.uid
FROM perinfo p
INNER JOIN likes l
ON p.uid = l.uid
INNER JOIN places pl
ON p.uid = pl.uid
WHERE p.hfor = 2
GROUP BY p.uid
HAVING SUM(pl.place = 'walhaba') >= 1 -- <== must have a match
AND SUM(l.likeID = 34) >= 1 -- <== must have a match
SQLFiddle Demo
You can use the DISTINCT keyword to remove duplicated uid's:
SELECT DISTINCT p.uid
FROM perinfo p
LEFT JOIN likes l ON l.uid = p.uid
LEFT JOIN places pl ON pl.uid = p.uid
WHERE l.likeid = 34
AND pl.place = 'Walhaba'
AND p.hfor = 2
Update
The following is the equivalent SQL using the GROUP BY clause:
SELECT p.uid
FROM perinfo p
LEFT JOIN likes l ON l.uid = p.uid
LEFT JOIN places pl ON pl.uid = p.uid
WHERE l.likeid = 34
AND pl.place = 'Walhaba'
AND p.hfor = 2
GROUP BY p.uid