Join multiple rows give one distinct row - sql

My SQL statement returns the following
SQLID Col1 Col2 Col3
14945 NULL NULL sdf
14945 NULL xyz NULL
14945 abc NULL NULL
where as I would like it to return
SQLID Col1 Col2 Col3
14945 abc xyz sdf
Please help.
The schema is such that I have a table which contains SQLID's. And a second table which contains SQLID's as the FK to first table and the col1, col2 and col3. Currently I am just doing a join on SQLId
Select
t1.SQLID, t2.Col1, t2.col2, t2.col3
from
Table1 t1
join
table2 t2 on t1.SQLId = t2.SQLid

EDIT: if Col1, Col2, Col3 are DATETIME datatype (as per following comment)
You can use;
SELECT SQLID, MAX(ISNULL(Col1,0)) AS Col1,
MAX(ISNULL(Col2,0)) AS Col2, MAX(ISNULL(Col3,0)) AS Col3
FROM YourTable
GROUP By SQLID

Related

How to use a variable as a select statement and then sum multiple values in a variable?

I have multiple rows with the following columns:
col1
col2
col3
col4
I want to say if rows where col3 equals col2 of other rows where col1 equals 'a111', then sum col4 of the rows where col3 equals col2 of other rows where col1 equals 'a111', and then rename the sum column to "Total".
Example table with the four columns and four rows:
col1 col2 col3 col4
---- ---- ---- ----
a222 a333 4444
a111 a333
a555 a444 1111
a111 a444
I've tried the following but it does not work.
Declare
var1 = Select col2 from table1 where col1='a111';
var2 = Select col3 from table1 where col3=var1;
var3 = Select col4 from table1 where col3=var1;
Begin
If var2=var1
Then Select SUM(var3) As "Total";
End
Expected result is:
Total
5555
I do not have the strongest of knowledge in programming overall or Oracle. Please ask any questions and I will do my best to answer.
Your logic is convoluted and hard to follow without an example of the data you have and an example of the data you want.. but translating your pseudocode into sql gives:
Declare
var1 = Select col2 from table1 where col1='[table2.col2 value]';
Called "find" in my query
var2 = Select col3 from table1 where col3=var1;
var3 = Select col4 from table1 where col3=var1;
Achieved by joining the table back to the "find"
Begin
If var2=var1
Then Select SUM(var3) As "Total";
End
Achieved with a sum of var3 on only rows where var1=var2, in "ifpart"
SELECT SUM(var3) FROM
(
SELECT alsot1.col3 as var2, alsot1.col4 as var3
FROM
table1 alsot1
INNER JOIN
(
SELECT t1.col2 as var1
FROM table1 t1 INNER JOIN table2 t2 ON t1.col1 = t2.col2
) find
ON find.var1 = alsot1.col3
) ifpart
WHERE
var1 = var2
This could be simplified, but I present it like this because it matches your understanding of the problem. The query optimizer will rewrite it anyway when the time comes to run it so it only pays to start messing with how it's done if performance is poor
By the way, you clearly said that two tables join via a common named col2 but you then in your pseudocode said the tables join on col1=col2. I followed your pseudocode
This sounds like something that hierarchical queries could handle. E.g. something like:
WITH your_table AS (SELECT NULL col1, 'a222' col2, 'a333' col3, 4444 col4 FROM dual UNION ALL
SELECT 'a111' col1, 'a333' col2, NULL col3, NULL col4 FROM dual UNION ALL
SELECT NULL col1, 'a555' col2, 'a444' col3, 1111 col4 FROM dual UNION ALL
SELECT 'a111' col1, 'a444' col2, NULL col3, NULL col4 FROM dual UNION ALL
SELECT 'a666' col1, 'a888' col2, NULL col3, NULL col4 FROM dual UNION ALL
SELECT NULL col1, 'a777' col2, 'a888' col3, 7777 col4 FROM dual)
SELECT col1,
SUM(col4) col4_total
FROM (SELECT connect_by_root(col1) col1,
col4
FROM your_table
CONNECT BY col3 = PRIOR col2
START WITH col1 IS NOT NULL) -- start with col1 = 'a111')
GROUP BY col1;
COL1 COL4_TOTAL
---- ----------
a666 7777
a111 5555
Nevermind. I believe I've determined the answer myself. I over complicated what I wanted. Thank you anyway.
Answer:
Select Sum(col4) as "Total" from table1 where col3 in (Select col2 from table1 where col1='a111')

Need two rows after join from single row based on two columns

I have a table1 with three columns and a table2 with single column.
If the value of first column is Y then I need a particular value from table 2 as a row in another table after join and if the second column is Y then I need a particular value from table 2 as another row in 3rd table after join. There is no common column in both the tables.
If two columns are in a row have Y as value then I need two rows in the final table after join. I'm using case right now for joining, but only one column is getting checked.
Can someone help me with this?
table1
--------------------
col1 col2 col3(pk)
--------------------
y n 123
y y 456
table2
--------------------
col1
--------------------
col1Y
col2Y
Expected output
table1
--------------------
col1 col2
--------------------
123 col1Y
456 col1Y
456 col2Y
select col3 as col1, 'col1y' as col2 from myTable where col1 = 'y'
union
select col3 as col1, 'col2y' as col2 from myTable where col2 = 'y'
--order by col1, col2;
SQLFiddle sample
you also can check how to transpose tables with pivot command
SQL transpose full table
We can unpivot and join to get the results you're looking for:
declare #table1 table (col1 char(1),col2 char(1),col3 int)
insert into #table1(col1,col2,col3) values
('y','n',123) ,
('y','y',456)
declare #table2 table (col1 char(5))
insert into #table2 (col1) values
('col1Y'),('col2Y')
select
u.col3 as col2,t2.col1 as col2
from
#table1 t1
unpivot
(cval for cname in (col1,col2)) u
cross apply
(select cname + cval as Complete) v
inner join
#table2 t2
on
v.complete = t2.col1
Result:
col1 col2
----------- -----
123 col1Y
456 col1Y
456 col2Y
But after the unpivot and cross apply, we didn't really need table2 at all (we could have just filtered down to rows where cval is Y). But for now I've included it in case I'm missing something or there's more to build up in the query.
Not sure if you need table2 but here is where you could do it with case statement.
SELECT col1, col2 from (
SELECT
CASE col1
WHEN 'y' THEN col3
ELSE 'null'
END AS col1,
CASE col1
WHEN 'y' THEN 'col1Y'
ELSE 'null'
END AS col2
from table1 as tbl1
union all
select
CASE col2
WHEN 'y' THEN col3
ELSE 'null'
END AS col1,
CASE col2
WHEN 'y' THEN 'col2Y'
ELSE 'null'
END AS col2
FROM table1 as tbl2) as tbl
where tbl.col1 <> 'null';
SQL Fiddle Sample

How to use and "in" clause in "having" in HIVE?

I have my data in sometable like this:
col1 col2 col3
A B 3
A B 1
A B 2
C B 1
And I want to get all of the unique groups of col1 and col2 that contain certain rows of col3. Like, all groups of col1 and col2 that contain a "2".
I wanted to do something like this:
select col1, col2 from sometable
group by col1, col2
having col3=1 and col3=2
But I want it to only return groups that have an instance of both 1 and 2 in col3. so, the result after the query should return this:
col1 col2
A B
How do I express this in HIVE? THANK YOU.
I don't know why others deleted answers that where correct and then almost correct but I will put their's back up.
SELECT col1, col2, COUNT(DISTINCT col3)
FROM
sometable
WHERE
col3 IN (1,2)
GROUP BY col1, col2
HAVING
COUNT(DISTINCT col3) > 1
If you actually want to return all of the records that meet your criteria you need to do a sub select and join back to the main table to get them.
SELECT s.*
FROM
sometable s
INNER JOIN (
SELECT col1, col2, COUNT(DISTINCT col3)
FROM
sometable
WHERE
col3 IN (1,2)
GROUP BY col1, col2
HAVING
COUNT(DISTINCT col3) > 1
) t
ON s.Col1 = t.Col1
AND s.Col2 = t.Col2
AND s.col3 IN (1,2)
The gist of this is narrow/filter your rowset to the rows that you want to test col3 IN (1,2) then count the DISTINCT values of col3 to make sure both 1 and 2 exist and not just 1 & 1 or 2 & 2.
I think below mentioned query will be useful for your question.
select col1,col2
from Abc
group by col1,col2
having count(col1) >1 AND COUNT(COL2)>2

SQL - Delete repeated rows in table

I need to delete the repeated row-
I have this table-
source
The result that I need-
result
*keep only one combination of 2 column (the order is not important)
Thanks! (:
Here is one method that should be efficient:
select col1, col2
from t
where col1 <= col2
union all
select col1, col2
from t
where col1 > col2 and
not exists (select 1 from t t2 where t2.col1 = t.col2 and t2.col2 = t.col1);
Note: This is a SQL select statement, so it does not delete rows in the table. You seem to want the results from a query, not to modify the underlying table.
My interpretation of the spec "keep only one combination of 2 column, [column] order not important":
SELECT col1, col2
FROM t
WHERE col1 <= col2
UNION
SELECT col2, col1
FROM t
WHERE col1 > col2;

Select a dummy column with a dummy value in SQL?

I have a table with the following
Table1
col1 col2
------------
1 A
2 B
3 C
0 D
Result
col1 col2 col3
------------------
0 D ABC
I am not sure how to go about writing the query , col1 and col2 can be selected by this
select col1, col2 from Table1 where col1 = 0;
How should I go about adding a col3 with value ABC.
Try this:
select col1, col2, 'ABC' as col3 from Table1 where col1 = 0;
If you meant just ABC as simple value, answer above is the one that works fine.
If you meant concatenation of values of rows that are not selected by your main query, you will need to use a subquery.
Something like this may work:
SELECT t1.col1,
t1.col2,
(SELECT GROUP_CONCAT(col2 SEPARATOR '') FROM Table1 t2 WHERE t2.col1 != 0) as col3
FROM Table1 t1
WHERE t1.col1 = 0;
Actual syntax maybe a bit off though