I have two almost identical MySQL tables besides a date column, and I would like to merge them with a select query to create a final table displaying both dates.
If there is a unique acc_id in one table -> i want to default the amount in the other to 0.
Here is an example of what i mean:
Table1:
id
acc_id
name
aug_amount
1
123
name1
100
2
456
name2
200
3
333
name3
300
Table2:
id
acc_id
name
sep_amount
1
123
name1
200
2
456
name2
300
3
444
name4
400
Merged table:
acc_id
name
aug_amount
sep_amount
123
name1
100
200
456
name2
200
300
333
name3
300
0
444
name4
0
400
Is there a way i can achieve this with a singular SQL query? I've been playing around for a while but i cant seem to crack it.
Help appreciated! Thanks for reading.
Ignoring the PK column, here is one solution where we union the two tables and then select from it:
select acc_id, name, sum(aug_amount) as aug_amount, sum(sep_amount) as sep_amount
from (
select acc_id, name, aug_amount, 0 as sep_amount
from table1
union
select acc_id, name, 0, sep_amount
from table2
)z
group by acc_id, name
order by name;
acc_id
name
aug_amount
sep_amount
123
name1
100
200
456
name2
200
300
333
name3
300
0
444
name4
0
400
View on DB Fiddle
Related
I have two tables and need to swap the values of a column in each table - I can do this when they are in the same table but when I try to do this with different tables then the second value is already overwritten so gets lost.
For example:
table1
id user_id currency col2 col3......
1 1 10 Bob 2018-04-16
2 2 150 Tom 2018-05-17
3 3 60 Phil 2018-06-04
4 4 125 Jon 2017-12-01
5 5 35 Mike 2018-07-21
table2
id user_id salary col2 col3......
1 1 USD 16 Active
2 2 USD 17 Active
3 3 GBP 21 Left
4 4 CAD 16 Active
5 5 AUD 19 Active
I need these to look like:
table1
id user_id currency col2 col3......
1 1 USD Bob 2018-04-16
2 2 USD Tom 2018-05-17
3 3 GBP Phil 2018-06-04
4 4 CAD Jon 2017-12-01
5 5 AUD Mike 2018-07-21
table2
id user_id salary col2 col3......
1 1 10 16 Active
2 2 150 17 Active
3 3 60 21 Left
4 4 125 16 Active
5 5 35 19 Active
I tried:
UPDATE table1 t1, table2 t2
SET t1.currency=t2.salary, t2.salary=t1.currency
WHERE t1.user_id=t2.user_id;
but this does not work (currency gets set correctly but not the salary), is it possible to do?
Swap two columns values between two tables looked like a possible solution but the solution is changing table names as all the columns need swopped whereas I only need single columns swapped.
I believe you'll need to use a mix of both DDL and DML to do this.
First off you'll need to rename one of the columns to be swapped and add a column to hold the new value:
alter table table1 change currency salary int;
alter table table1 add currency varchar(3) after salary;
then update each table independently:
update table1 t1, table2 t2
set t1.currency = t2.salary
where t1.user_id = t2.user_id;
update table1 t1, table2 t2
set t2.salary = t1.salary
where t1.user_id = t2.user_id;
and finally remove the extra column:
alter table table1 drop salary;
I have duplicate rows in table, i want sum of quantity of duplicate row and average of purchase rate of duplicate rows, let me explain you by example.
Please give me mysql query to acheive desired output.
Problem Table
===================================================
POID itemid quantity purchaserate
1 1 100 100
2 2 100 100
3 3 100 100
4 1 80 200
5 1 40 150
6 3 100 400
====================================================
Desired output
===================================================
itemid totalquantity avgpurchaserate
1 220 145.45
2 100 100
3 200 250
===================================================
Tried below query
select itemid, sum(quantity), avg(purchaserate)
from test
group by itemid
Output
itemid |sum(quantity) | avg(purchaserate)
1 | 220 | 150
2 | 100 | 100
3 | 200 | 250
You can use aggregation function as sum and avg and group by the column you need. In your case itemid
select itemid, sum(quantity) avg(purchaserate)
from my_table
group by itemid
I have two tables
Table 1 Table2
id_1 id_2 name
1 10 name1
2 20 name2
3
4
5
I need a query to get this another one, where for each id_1 the result gets as many registers as table 2 has.
Table3
id_3 id_1 id_2 name
1 1 10 name1
2 1 20 name2
3 2 10 name1
4 2 20 name2
5 3 10 name1
6 3 20 name2
7 4 10 name1
8 4 20 name2
9 5 10 name1
10 5 20 name2
Could you help me?
Thanks
EDIT:
Well, thanks to both of you.
Finally I got an easy solution.
SELECT * FROM table1 CROSS JOIN table2
I didnĀ“t know the CROSS JOIN operator. And that gives you the combination of each register from the first table with each register from the second.
Thanks again
Try with this:
INSERT INTO Table3 SELECT t1.id_1,t2.id_2,t2.name FROM Table1 t1, Table2 t2
This query should work:
insert into table3 (id_1,id_2,name) values select id_1,id_2,name from table1,table2;
I guess that id_3 is an autoincrement
I have two tables that aren't really associated, but need to be combined. So I'm using union all on the two tables. The unioned tables are ordered by date, so rows from one table are dispersed among rows from the other table. What I need to do is get a running count of a column so I can group elements.
To explain further, table A holds dates of when a container is emptied, while table B holds daily entries for content of the container. I need to union the two tables so I have one table where I can get the sum of the information for a container before the container is emptied.
So I need something like this:
Table A:
Location_ID Empty Date
123 3/2/13
123 3/10/13
123 4/1/13
Table B:
PSI Entry Date Location_ID
120 2/28/13 123 (same for all)
130 3/1/13
100 3/8/13
110 3/9/13
200 3/18/13
180 3/20/13
So the unioned table after some magic would look like:
Table C...:
Location_ID Date PSI Emptied
123 2/28/13 120 0
123 3/1/13 130 0
123 3/2/13 null 1
123 3/8/13 100 0
123 3/9/13 110 0
123 3/10/13 null 1
123 3/18/13 200 0
123 3/20/13 180 0
123 4/1/13 null 1
What I need to do is have a grouping such that I can have a table like this
Table C_b
Location_ID Date PSI Emptied Group
123 2/28/13 120 0 1
123 3/1/13 130 0 1
123 3/2/13 null 1 1
123 3/8/13 100 0 2
123 3/9/13 110 0 2
123 3/10/13 null 1 2
123 3/18/13 200 0 3
123 3/20/13 180 0 3
123 4/1/13 null 1 3
How can I get that grouping in that way? I have to make it work in SQL Server 2008. I have tried using Count, and Rank, and Row_Number. But the problem with those is that it won't do a running count, it will just say the total count in each row.
Try this query:
DECLARE #MyTable TABLE(
EntryDate DATE NOT NULL,
Emptied BIT NOT NULL
);
INSERT INTO #MyTable (EntryDate,Emptied)
VALUES
('2013-01-01',0),
('2013-01-02',0),
('2013-01-03',1),
('2013-01-04',0),
('2013-01-05',0),
('2013-01-06',1),
('2013-01-07',0),
('2013-01-08',0),
('2013-01-09',1);
DECLARE #TableWithRowNum TABLE(
EntryDate DATE NOT NULL,
Emptied BIT NOT NULL,
RowNum INT PRIMARY KEY
);
INSERT INTO #TableWithRowNum (EntryDate,Emptied,RowNum)
SELECT crt.*,ROW_NUMBER() OVER(ORDER BY crt.EntryDate) AS RowNum
FROM #MyTable crt;
WITH RecCTE
AS(
SELECT
crt.EntryDate,
crt.Emptied,
crt.RowNum,
1 AS Grp
FROM #TableWithRowNum crt
WHERE crt.RowNum=1
UNION ALL
SELECT
crt.EntryDate,
crt.Emptied,
crt.RowNum,
CASE WHEN prev.Emptied=1 THEN prev.Grp+1 ELSE prev.Grp END
FROM #TableWithRowNum crt INNER JOIN RecCTE prev ON crt.RowNum=prev.RowNum+1
)
SELECT * FROM RecCTE
OPTION(MAXRECURSION 0); -- Default value for MAXRECURSION is 100
GO
Results:
EntryDate Emptied RowNum Grp
---------- ------- ------ ---
2013-01-01 0 1 1
2013-01-02 0 2 1
2013-01-03 1 3 1
2013-01-04 0 4 2
2013-01-05 0 5 2
2013-01-06 1 6 2
2013-01-07 0 7 3
2013-01-08 0 8 3
2013-01-09 1 9 3
My table structure is as follows
id int
name varchar 50
catid int
Sample data
id name catid
---------------------------------------------------------
1 AAA 1
2 BBB 1
3 CCC 1
4 DDD 2
5 EEE 2
6 FFF 1
7 GGG 2
8 HHH 2
9 III 1
I want query such as it get me 1 row from each category for each page in pagination
Now for 1st Page I need data as
id name catid
---------------------------------------------------------
1 AAA 1
4 DDD 2
Now for 2nd Page I need data as
id name catid
---------------------------------------------------------
2 BBB 1
5 EEE 2
Now for 3rd Page I need data as
id name catid
---------------------------------------------------------
3 CCC 1
7 GGG 2
and so on.
How can I achieve this.
SELECT * FROM table WHERE catid = 1 LIMIT :pageno 1
SELECT * FROM table WHERE catid = 2 LIMIT :pageno 1
I think, this will be simplest query to get required result.
This worked for me (MySQL 5.1 on Linux)
SELECT id, name, catid FROM
(SELECT id, name, catid FROM t WHERE catid=1 LIMIT 2,1) AS t1
UNION (SELECT id, name, catid FROM t WHERE catid=2 LIMIT 2,1)
ORDER BY catid
The 2 in the limit is the page number. Hence the output of this one is for the second page.
Yes, as Pradeep said, a LIMIT clause would be the simplest way to do it in MySQL. You'll still need a little bit of coding in PHP to produce clickable page numbers for your users.