merge two tables without common columns - mysql

I would like to merge two tables without common columns in MSSQL while keep all the rows in each table as separate row in the merged table.
Scenario:
Table A Col1 Col2
1 1.Col1 1.Col2
2 2.Col1 2.Col2
Table B Col3
3 3.Col3
Here is what i expected:
Table Col1 Col2 Col3
1 1.Col1 1.Col2 Null
2 2.Col1 2.Col2 Null
3 Null Null 3.Col3

Simply use Union and select NULL for other columns to avoid:
All queries combined using a UNION, INTERSECT or EXCEPT operator must
have an equal number of expressions in their target lists.
Demo:-
Create table #Table1 ( A int, Col1 varchar (10), Col2 varchar(10))
Create table #Table2 ( b int, Col3 varchar (10))
insert into #Table1 values (1,'1.Col1',' 1.Col2')
insert into #Table1 values (2,'2.Col1','2.Col2')
insert into #Table2 values (3,'3.Col3')
select A,Col1,Col2,null as Col3 from #Table1
union
select B,null,null,Col3 from #Table2
go
drop table #Table1
go
drop table #Table2
Result:-

Select A,Col1,Col2,null as Col3 from tblA Union All Select B,null ,null ,Col3 from tblB

Related

Mysql: How to delete all duplicates that violate UNIQUE constraint

I want to add a UNIQUE index to a table, like this:
ALTER TABLE `mytable` ADD UNIQUE `myunique_name`(`first`, `second`, `third`);
Mysql responds with:
Duplicate entry '1-2-3' for key 'myunique_name'
I know for sure that this combination is just one out of thousands that violate the constraint.
In this special case I know for sure that all the rows that contain the same values in the three specified columns also contain the same data in the other relevant fields (the primary index differs of course, but is irrelevant), therefore all the duplicates can be deleted.
Is there a way to do delete all duplicate entries but keep one (doesn't matter which primary key is kept) so that the unique index can be added?
CREATE TEMPORARY TABLE IF NOT EXISTS MyTable engine=memory
select 1 as id, 1 col1,1 col2,1 col3
union all
select 2 as id, 2 col1,2 col2,2 col3
union all
select 3 as id, 3 col1,3 col2,3 col3
union all
select 4 as id, 4 col1,4 col2,4 col3
union all
select 5 as id, 1 col1,1 col2,1 col3
union all
select 6 as id, 2 col1,2 col2,2 col3
CREATE TEMPORARY TABLE IF NOT EXISTS MyDuplicateTableWithCount engine=memory
select col1 , col2 , col3, count(*) Count_1
from MyTable
group by col1 , col2 , col3
having count(*)>1
select a.* from MyTable a
inner join
(select col1 , col2 , col3
from MyDuplicateTableWithCount
) b
on a.col1 =b.col1 and a.col2 =b.col2 and a.col3 =b.col3
order by a.id
After getting the duplicate id's write your delete query specifyinging duplicate id's as
delete from myTable where id in (5,6)
Also use below query using myTable from above
CREATE TEMPORARY TABLE IF NOT EXISTS MyTable2 engine=memory
SELECT MIN(id) as id, Col1, Col2, Col3
FROM MyTable
GROUP BY Col1, Col2, Col3
DELETE a FROM MyTable as a
LEFT JOIN (
SELECT * from MyTable2
) as b ON
b.id = a.id
WHERE
b.id IS NULL

MYSQL: Insert one value from another table while populating other columns regularly

Lets say we have a table (1):
id | col1 | col2
And another table (2):
id | col3
Task is to insert all col3 distinct values to col1 at the same time populating col2 with random integer value
A couple of solutions here.
This uses a sub query to return the distinct values of col2.
INSERT INTO table1 (id, col1, col2)
SELECT NULL, col2, FLOOR(RAND()*(1000))+1
FROM
(
SELECT DISTINCT col2
FROM table2
)
The following abuses the GROUP BY clause to only generate rows for distinct values of col2. While this should be OK on a default install of MySQL, it might not work depending on the options set up for your installation and also probably wouldn't work in other flavours of SQL.
INSERT INTO table1 (id, col1, col2)
SELECT NULL, col2, FLOOR(RAND()*(1000))+1
FROM table2
GROUP BY col2

how to get the desired output in sql server 2008

Table Structure
EID COLA COLB
1 name A
1 age 23
1 city hyd
1 email abc#live.in
1 mobile 45126
2 name B
2 age 43
2 city bang
3 name C
3 age 13
3 city bang
3 email jdf#live.in
I would like to have the output as below
ID||COLA||COLB
1||name||A
1||age||23
1||city||hyd
1||email||abc#live.in
1||mobile||45126
2||name||B
2||age||43
2||city||bang
2||email||NULL
2||mobile||NULL
3||name||C
3||age||13
3||city||bang
3||email||jdf#live.in
3||mobile||NULL
Can you kindly let me know how to achieve this output.
how to display the result where any of the mandatory fields (name,age,city,email,mobile)are missing then it should display as that field as Null, in the query we would provide in the where clause by filtering a single id value and cola as (name,age,city,email,mobile)
my Query:
select
case colA
when cola then colA+'||'+colB
end
from tbl
where cola in ('name','age','city','email','mobile')
Let me start by saying that what you are asking would have been really easy if your table structure had required columns like name, age, city etc. Name Value Pair is not a good design for such tables, not to mention serious performance issues which will plague any solution against this structure.
Having said that, you can use either PIVOT / UNPIVOT or an Attribute table (a table containing list of attribute required) and GROUP BY with CROSS JOIN.
Sample Data
DECLARE #table1 TABLE(
EID INT, COLA VARCHAR(30), COLB VARCHAR(30) )
INSERT INTO #table1 VALUES
(1,'name','A'),
(1,'age','23'),
(1,'city','hyd'),
(1,'email','abc#live.in'),
(1,'mobile','45126'),
(2,'name','B'),
(2,'age','43'),
(2,'city','bang'),
(3,'name','C'),
(3,'age','13'),
(3,'city','bang'),
(3,'email','jdf#live.in');
Query using PIVOT / UNPIVOT
SELECT EID, COLA,NULLIF(COLB,'') COLB
FROM
(
SELECT EID,ISNULL([name],'') name,ISNULL([age],'') [age],ISNULL([city],'') [city],ISNULL([email],'') [email],ISNULL([mobile],'') [mobile]
FROM (SELECT EID,COLA,COLB
FROM #table1) T
PIVOT ( MAX(COLB) FOR COLA IN ( [name],[age],[city],[email],[mobile] ) ) AS pvt
) tbl
UNPIVOT (COLB FOR ColA IN (name,age,city,email,mobile)) AS Upvt
Notice that I am using ISNULL(col,'') because UNPIVOT excludes NULL values. If '' is a valid value for you, you can use another string to denote NULL or use the GROUP BY solution.
Query using Attribute table and GROUP BY with CROSS JOIN
;WITH Cols(Name) AS
(
SELECT 'name' UNION ALL SELECT 'age' UNION ALL SELECT 'city' UNION ALL SELECT 'email' UNION ALL SELECT 'mobile'
)
SELECT t.EID,C.Name,t1.COLB
FROM
(
SELECT EID
FROM #table1
GROUP BY EID
) t
CROSS JOIN Cols c
LEFT JOIN #table1 t1 ON t1.EID = t.EID and t1.COLA = C.Name
CREATE TABLE DesireOutput(EID nvarchar(10),COLA NVARCHAR(10),COLB nvarchar(50))
INSERT INTO DesireOutput VALUES ('1','name','A' )
INSERT INTO DesireOutput VALUES ('1','age','23')
INSERT INTO DesireOutput VALUES ('1','city','hyd')
INSERT INTO DesireOutput VALUES ('1','email','abc#live.IN')
INSERT INTO DesireOutput VALUES ('1','mobile','45126')
INSERT INTO DesireOutput VALUES ('2','name','B')
INSERT INTO DesireOutput VALUES ('2','age','43')
INSERT INTO DesireOutput VALUES ('2','city','bang')
INSERT INTO DesireOutput VALUES ('3','name','C')
INSERT INTO DesireOutput VALUES ('3','age','13')
INSERT INTO DesireOutput VALUES ('3','city','bang')
INSERT INTO DesireOutput VALUES ('3','email','jdf#live.IN')
DECLARE #t AS TABLE ( ColA NVARCHAR(50) )
INSERT INTO #t
SELECT DISTINCT
D.COLA
FROM DesireOutput D
SELECT t.EID , c.ColA , t1.COLB FROM ( SELECT
EID FROM DesireOutput GROUP BY EID
) t
CROSS JOIN #t c
LEFT JOIN DesireOutput t1 ON t1.EID = t.EID
AND t1.COLA = c.ColA ORDER BY EID

How to get SUM of certain column without losing all rows?

CREATE TABLE tmp ( col1 int, col2 int );
INSERT INTO tmp VALUES (1,3), (2,5), (3,7);
SELECT col1, col2, SUM(col2) AS Total FROM tmp; -- ???
The SELECT statement leaves me with this data set:
col1 col2 Total
1 3 15
Is there a way to allow all the rows to appear without introducing a subquery, so that the result is this:
col1 col2 Total
1 3 15
2 5 15
3 7 15
You can use a cross join to avoid a subquery:
SELECT t1.col1, t1.col2, sum(t2.col2) sum_col2
from tmp t1
cross join tmp t2
group by 1, 2
See SQL fiddle
Note that this only works if combinations of col1 and col2 are unique.

Create a new table from merging two tables with union

I have two tables with the same columns.
I can merge them with UNION
select * from table1
union
select * from table2;
How do I create a new table with the same contents and columns as that query?
You can use CREATE TABLE ... SELECT statement.
CREATE TABLE new_table
SELECT * FROM table1
UNION
SELECT * FROM table2;
create table new_table as
select col1, col2 from table1
union
select col1, col2 from table2
Make sure you select same set of columns from tables in union.
Or even you can explicitly define create table (we generally use in our project).
CREATE TABLE IF NOT EXISTS auditlog (
user_id varchar(30) NOT NULL default '',
user_ip varchar(255) NOT NULL default '',
........
........
KEY ie1 (user_id) )
union=(auditlog_2,auditlog_3,auditlog_4) engine=merge insert_method=last;