I have two tables that I need to merge.
Table 1 is :
ID
Product code
Spend
1
101
100
1
102
200
1
103
300
2
201
400
3
301
500
3
302
600
Table 2 has
ID
Product code
Spend
Product tenure
1
101
100
20
1
102
200
30
3
302
600
40
I want to merge these such that only ID's present in table 2 are retained from table 1. Table 2 does not contain all the product codes for each ID, but I want my final table to have it.
Output must have
ID
Product code
Spend
Product tenure
1
101
100
20
1
102
200
30
1
103
300
3
301
500
3
302
600
40
Any help on this would be appreciated. I tried left join on ID, but it produces many duplicates.
SELECT *,
(
SELECT `product_tenure`
FROM `second_table`
WHERE `second_table`.`id` = `first_table`.`id`
AND `first_table`.`product_code` = `second_table`.`product_code`
) product_tenure
FROM `first_table`
WHERE `id` IN (SELECT DISTINCT `id` FROM `second_table`)
Explaination:
Select id from second table, which wanted to keep from first table.
Because the product_tenure only in second_table select them with combined id and product_code
Result:
Test this:
SELECT *
FROM t1
LEFT JOIN t2 AS t21 USING (ID, `Product code`)
WHERE EXISTS ( SELECT NULL
FROM t2 AS t22
WHERE t1.ID = t22.ID )
PS. The query will return 2 Spent columns (they're present in each table, and nothing prevents their values to be not equal...) - so replace an asterisk with definite columns list.
Related
so I have 3 tables in my db, where all 3 tables contains a column which have similar data, but name of that column is different on all the 3 tables, below is an example.
Ban Table
user_id
ban_user_id
ban_date
reason
end_date
1300
1
xyz
xyz
xyz
32
1
xyz
xyz
xyz
43
2
xyz
xyz
xyz
Reports Table
user_id
last_modified_user_id
report_date
reason
end_date
1300
1
xyz
xyz
xyz
32
2
xyz
xyz
xyz
43
2
xyz
xyz
xyz
Warning Table
user_id
warning_user_id
warning_date
reason
end_date
1300
1
xyz
xyz
xyz
32
2
xyz
xyz
xyz
43
3
xyz
xyz
xyz
Now I want to fetch data by combining these 3 tables, where ban_user_id, last_modified_user_id, and warning_user_id contains the data of staff member who took the actions, so i want to group the data by the staff id.
The output i am looking for is as follows:
staff_id
total_reports
total_bans
total_warnings
1
1
2
1
2
2
1
1
3
0
0
1
where it is counting the data for each table by grouping the 2nd column, ban_user_id, last_modified_user_id, warning_user_id respectively. And than combining the data.
I tried things with UNION All and stuffs, but it didn't work out.
Thankyou in advance for your help
Use UNION ALL for all 3 tables and then aggregate:
SELECT staff_id,
COUNT(report) AS total_reports,
COUNT(ban) AS total_bans,
COUNT(warning) AS total_warnings
FROM (
SELECT last_modified_user_id AS staff_id, 1 AS report, null AS ban, null AS warning FROM Reports
UNION ALL
SELECT ban_user_id, null, 1, null FROM Ban
UNION ALL
SELECT warning_user_id, null, null, 1 FROM Warning
) t
GROUP BY staff_id;
Or:
SELECT staff_id,
SUM(report) AS total_reports,
SUM(ban) AS total_bans,
SUM(warning) AS total_warnings
FROM (
SELECT last_modified_user_id AS staff_id, 1 AS report, 0 AS ban, 0 AS warning FROM Reports
UNION ALL
SELECT ban_user_id, 0, 1, 0 FROM Ban
UNION ALL
SELECT warning_user_id, 0, 0, 1 FROM Warning
) t
GROUP BY staff_id;
See the demo.
You can use Table joins (Inner/outer/left/right) to get the data instead of union.
I'm assuming the staff_id is the equivalent of user_id column as you haven't mentioned anything about that, so your script will look something like this:
SELECT W.user_id AS staff_id,
B.ban_user_id,
R.last_modified_user_id,
W.warning_user_id
FROM Warning AS W
LEFT JOIN Reports AS R on R.user_id = W.user_id
LEFT JOIN Ban AS B on B.user_id = W.user_id
group by W.user_id
Please help me with writing a query for the following condition. I have a table which I have listed below
ID Wt1 Wt1_Type Wt2 Wt2_Type Wt3 Wt3_Type Wt4 Wt4_Type
--------------------------------------------------------------
1 200 1 220 1 300 2 400 3
2 100 4 150 3 100 5 120 1
3 100 3 110 1 200 5 100 4
I want a query to sum all the the weights (wt1, wt2, wt3, wt4) grouped on the weight type (wt1_type, wt2_type, wt3_type, wt4_type).
The output should look like
Wt_type Total
1 650
2 300
3 650
4 200
5 300
Can someone please help me draft a mysql query to get this result ?
Thanks
You can try below - using union all and subquery
select Wt_Type,sum(Wt) as total from
(
select Wt1_Type as Wt_Type,Wt1 as Wt from tablename
union all
select Wt2_Type ,Wt2 from tablename
union all
select Wt3_Type ,Wt3 from tablename
union all
select Wt4_Type ,Wt4 from tablename
)A group by Wt_Type
Rather than giving the answer by #fa06, which should work for you, I am going to suggest using a better table design. Here is how you should be storing your data:
ID Type Wt
-------------
1 1 200
2 4 100
3 3 100
4 1 220
5 3 150
6 1 110
7 2 300
8 5 100
9 5 200
10 3 400
11 1 120
12 4 100
Note that there is a single column which stores the type and a single column for that type's weight. Now your expected output just requires a very simple query:
SELECT Type, SUM(Wt) AS Total
FROM yourTableUpdated
GROUP BY Type;
Databases are really good at performing operations across rows, much less so across columns.
Use this it should be work
select Wt_Type,sum(Wt) as total from ( select Wt1_Type as Wt_Type,Wt1 as Wt from tablename union all select Wt2_Type ,Wt2 from tablename union all select Wt3_Type ,Wt3 from tablename union all select Wt4_Type ,Wt4 from tablename )A group by Wt_Type
table:tab1
id date_time zoneid accountid slotid trequest bidder width height
_50832 2017-09-04 15:41:06 153 1654 153x468x60 10 aaa 468 60
_50832 2017-09-04 15:41:06 152 1654 152x468x60 10 bbb 468 60
table:tab2
id date_time zoneid accountid slotid bidder count
_50832 2017-09-04 15:41:06 152 1654 152x468x60 bbb 6
_50832 2017-09-04 15:41:06 152 1654 152x468x60 bbb 4
_50832 2017-09-04 15:41:06 153 1654 153x468x60 aaa 9
_50832 2017-09-04 15:41:06 153 1654 153x468x60 aaa 1
below is my query:
SELECT SUM(req.trequest) as REQ, SUM(win.count) as IMP
FROM tab1 as req
JOIN tab2 as win ON (req.id=win.id AND req.zoneid=win.zoneid)
GROUP BY req.zoneid
I get below result,
REQ IMP
20 10
20 10
IMP count is correct but I get wrong REQ count. My expected result is
REQ IMP
10 10
10 10
How to get my expected result?
Lets find the sum of trequest and count separately based on zoneid and id.Then use these two results ( t1 and t2 ) in the inner join.
Count mismatch problem shown in the question occur due to multiple rows satisfying the joining conditions.
In this solution we will only have one entry for each zoneid in both the results ( t1 and t2 ). So the problem is avoided.
Note: You can remove the id column from the GROUP BY clause if it doesn't make any difference.
SELECT t1.id, t1.zoneid, t1.REQ, t2.IMP FROM
(SELECT id,zoneid,SUM(trequest) as REQ
FROM tab1 GROUP BY zoneid,id ) t1
INNER JOIN
(SELECT id,zoneid SUM(win.count) as IMP
FROM tab2 GROUP BY zoneid,id ) t2
ON t1.id = t2.id
AND t1.zoneid = t2.zoneid
Let's try first sumwin.count and group records in sub-query, after it join tables. Try in following:
SELECT SUM(req.trequest) as REQ, SUM(win.count) as IMP
FROM tab1 as req
JOIN (
SELECT SUM(win.count) as IMP, win.zoneid, win.id
FROM tab2 as win
GROUP BY win.zoneid, win.id) AS win ON req.id=win.id AND req.zoneid=win.zoneid
GROUP BY req.zoneid
Instead of req.zoneid. You should try win.zoneid. What seems is that the rows in table 1 are counted multiple times as zoneid in table 2 comes twice. So win.zoneid would group it and avoid the repetition.
Updated: The solution posted by #mayur panchal is the correct one as you don't need to SUM the rows in first table as they belong to different zoneid. If you SUM them you will obviously get the 20 repeated twice.
I have to do some reporting, involving various tables, and having couple of SUMs, COUNTs, etc and everything is OK. But the last thing I have to resolve is SUM by another which is not in the grouped columns.
I'll give you an example (stripped down from what I have) so you can understand the tongue-twister in the previous paragraph.
Suppose I have a query with a couple of joins that get me this result, or a temporary table, or whatever:
(this is a trimmed down version, in the original I have much more columns and groupbys)
APP_ID CAT_ID CAT_DESCRIP APP_START APP_END DETAIL_ID DET_QTY DETAIL_PRICE
1 1 Categ One 900 960 1 10 150.00
1 1 Categ One 900 960 2 8 20.00
1 1 Categ One 900 960 3 12 30.00
1 1 Categ One 900 960 4 5 100.00
2 2 Categ Two 600 720 5 12 150.00
2 2 Categ Two 600 720 6 10 50.00
3 2 Categ Two 1200 1260 7 5 20.00
I need to get something like this: (the bolded column is the important)
SELECT
CAT_ID,
CAT_DESCRIP,
SUM(DET_QTY) as TotalQTY,
SUM(DETAIL_PRICE) as TotalPrice,
COUNT(DISTINCT APP_ID) as CountOfApps,
(GET THE SUM OF (APP_END - APP_START) ONLY ONE TIME BY APP_ID INTO THIS CATEG) as TimeInMinutesByCategory
FROM
MyTable
GROUP BY
CAT_ID
And the result has to give me this:
CAT_ID CAT_DESCRIP TotalQTY TotalPrice CountOfApps TimeInMinutesByCategory
1 Categ One 35 300.00 1 60
2 Categ Two 27 220.00 2 180
Thanks for your help!
I think this will do the job... or if not, a little tweaking on the sytnax for max(app_start) - max(app_end) should do the job
The idea is, summarize the data in a subquery by app_id and cat_id. Select the max value of start and end, grouped by app_id and cat_id. Since there will only be one value per each distinct pair of app_id and cat_id, we're essentially just deduping.
Then, join the subquery to the main query and summarize by category id.
SELECT
a.CAT_ID,
a.CAT_DESCRIP,
SUM(a.DET_QTY) as TotalQTY,
SUM(a.DETAIL_PRICE) as TotalPrice,
COUNT(DISTINCT a.APP_ID) as CountOfApps,
SUM(b.TimeInMinutesByCategory) AS TimeInMinutesByCategory
FROM
MyTable AS a
INNER JOIN (
SELECT APP_ID, CAT_ID, max(app_start) - max(app_end) AS TimeInMinutesByCategory
FROM MyTable
GROUP BY APP_ID, CAT_ID) AS b
ON a.cat_id = b.cat_id
AND a.app_id = b.app_id
GROUP BY
a.CAT_ID
I have a table called temp_reading. It has the following columns (consumption is an index key):
id consumption total
1 100
1 200
1 300
1 400
2 50
2 100
3 200
4 250
Now I want to display total as
id consumption total
1 100 100
1 200 300
1 300 600
1 300 900
2 50 50
2 100 150
3 200 200
4 250 250
Is it possible to display like the above?
I tried the following query:
SELECT id,consumption,sum(consumption) as total
FROM temp_reading
GROUP BY consumption;
Please help me solve this.
I recommend that you add a Primary Key on your temp_reading table. (Read more about Primary Keys) This key will be unique per row. Then you can try this query:
SELECT TR.id
, TR.consumption
, TR.consumption + IFNULL(SUM(TR2.consumption), 0) AS Total
FROM temp_reading TR
LEFT JOIN temp_reading TR2 ON TR.id = TR2.id AND TR.pk > TR2.pk
GROUP BY TR.pk;
I've tried it in SQL Fiddle.
select id,sum(consumption) as total
from temp_reading
group by id;
I suggest you do not have the same ID (1,1,1.2,2...)
Try this:
SELECT id, consumption, IF(#s=#s:=id, #s2:=#s2+consumption, #s2:=consumption) AS total
FROM temp_reading, (SELECT #s:=0, #s2:=0);