Return differing rows in tsql - sql

I apologize for the basic non specific title. I can’t conceptualize how to ask this question or write the query I need in tsql. Any suggestions or guidance would be helpful. I have four columns that matter to me in a table:
c1(primarykey), c2, c3, c4
For any two rows, If c3 and c4 match but c2 doesn’t I want to return the rows. Amplify this to the entire table.
I’ve tried joining on a temp table then finding the difference through a left join on the table to itself but maybe I’m doing something incorrectly. Thank you in advance.

You could use:
WITH cte AS (
SELECT *, MIN(c2) OVER(PARTITION BY c3,c4) AS m, MAX(c2) OVER(PARTITION BY c3,c4) AS m2
FROM tab
)
SELECT *
FROM cte
WHERE m <> m2;

If you want to return the rows, then exists is a good way to go:
select t
from t
where exists (select 1
from t t2
where t2.c3 = t.c3 and t2.c4 = t.c4 and
t2.c2 <> t.c2
);
You do not mention NULL values in your question. If you have NULL values in any of the three columns, you would need to tweak the logic.
If you just wanted the c3/c4 pairs with different c2 values, you can use aggregation:
select c3, c4
from t
group by c3, c4
having min(c2) <> max(c2);
Finally, if you wanted to see pairs of non-matches on a single row, then:
select t.*, t2.c1, t2.c2
from t join
t t2
on t2.c3 = t.c3 and t2.c4 = t.c4 and
t2.c2 > t.c1;

With EXISTS:
select t.* from tablename t
where exists (
select 1 from tablename
where c2 <> t.c2 and c3 = t.c3 and c4 = t.c4
)

You can use Except
SELECT C1,C2,C3,C4 FROM TABLE1
EXCEPT
SELECT C4,C3,C2,C1 FROM TABLE1
This will check all the column values and if any of the value doesn't match then that record will be returns. More over you can add more columns to this query to match values.

Related

De-duplicate data in postgresql based on few columns

I have a table in psql
where column T1 represent time (t5> t4> t3> t2> t1)
I want to remove all the rows except the one with the latest time, with same value of column C1 and C2,
i.e I want
Can someone please help me with the query for this. I am new to psql so i am not able to figure out this on my own.
Thanks.
Use distinct on:
select distinct on (c1, c2) t.*
from t
order by c1, c2, t1 desc;
In a delete, you can use:
delete from t
where t.t1 < (select max(t2.t1)
from t t2
where t2.c1 = t.c1 and t2.c2 = t.c2
);

hive query to map keys to multiple values

I have a table with a structure similar to the one below:
|C1|C2|C3|
|K1|V1|??|
|K1|V2|??|
|K1|V3|??|
|K2|V2|??|
I need to write a query that checks if the key(lets say K1) maps to a specific value in any row (say V2). If it does the value in column C3 is taken as 1 otherwise its 0.
I'd appreciate any help.
The folloiwng query should give the results you want. The subquery identifies all C1 values which map to a certain value in C2 at least once. If so, then we render the C3 values as 1, otherwise we show 0.
SELECT
t1.C1,
t1.C2,
CASE WHEN t2.C1 IS NOT NULL THEN 1 ELSE 0 END AS C3
FROM yourTable t1
LEFT JOIN
(
SELECT C1
FROM yourTable
GROUP BY C1
HAVING SUM(CASE WHEN C2 = 'V1' THEN 1 ELSE 0 END) > 0
) t2
ON t1.C1 = t2.C1

combine two oracle sql results into single dataset

I have two selects and I want to combine them in such a way, that only one row that has key column matched in both selects are returned(one row in first select and one row in 2nd select). Is there any built-in way in Oracle 10g to achieve this?
I have two sql as below
Query 1:
select c11, c12 from table t1
where c11=1000
Query 2:
select c21, c22
from t2
where c21=1000
I want to combine both query 1 and query 2 on key columns(OPTYREVN_OPTY_XI, OPTYREVN_SEGMENT_XI and OPTYREVN_OPTYREVNCRM_ID). My output should contain only the only one row which found in results of query 1 and query 2.
I am not sure to use UNION or Intersect or left outer join.
Kindly suggest me some solution which will be helpful in this scenario. Thanks.
So, If I got you right, you want to have c1 , c2 , c33 , c21 , c22 and c 23 on one line, if both queries return only one line and no information can link them, this should work...
SELECT a.* , b.*
FROM (select c1, c2, c33
from t1, t3
where c1= 1000 and c33 is null) a ,
(select c21, c22, c23
from t2
where c21= 1000) b
/*WHERE...*/ --you could always use some condition linking a and b
I think you would want to use a join:
SELECT c1, c2, c33, c21, c22, c23
FROM t1 INNER JOIN t3 ON <key columns>
INNER JOIN t2
ON t1.c1 = t2.c21
WHERE t1.c1 = 1000
AND t3.c33 IS NULL;

SQL Server 2008 EXCEPT statement

Here is my example script:
SELECT c2, c3, c4 FROM Table1
EXCEPT
SELECT c2, c3, c4 FROM Table2
I'm successfully returning unique records from the left table that do not also exist in the right table. Both tables have identical schemas and for the most part identical data. The problem is that the unique id (let's call it column c1) does not match, so I need to exclude it in the EXCEPT query above. How can I return the same set of records, but with the unique IDs included?
I was thinking of using temporary tables, cursors and long WHERE statements inside the cursor, but that doesn't seem like a very elegant solution. is there another way to accomplish this seemingly simple task?
Can you take your supplied query, and simply inner join it with table 1 to get your 'c1' column?
SELECT T1.* FROM Table1 T1 INNER JOIN(
SELECT c2, c3, c4 FROM Table1
EXCEPT
SELECT c2, c3, c4 FROM Table2
) a on a.c2=T1.c2 and a.c3=T1.c3 and a.c4=T1.c4
Try this
SELECT A.c1, A.c2, A.c3, A.c4
FROM Table1 A
LEFT OUTER JOIN Table2 B ON A.c2 = B.C2 AND A.c3 = B.C3 AND A.c4 = B.C4
WHERE B.c1 IS NULL;
You probably can accomplish it using "NOT EXISTS" rather than "EXCEPT" since with "NOT EXISTS" you can specify conditions. Here's a thread that points this out: EXCEPT vs NOT EXISTS.
This is kind of ugly and, on large tables lacking "useful" indexes, might perform very poorly, but it will do the work:
SELECT t1.c1, t1.c2, t1.c3, t1.c4
from Table1 t1
inner join (-- Unique tuples
SELECT c2, c3, c4 FROM Table1
EXCEPT
SELECT c2, c3, c4 FROM Table2
) xx
on xx.c2 = t1.c2
and xx.c3 = t1.c3
and xx.c5 = t1.c4

Comma Separated list of rows of a column with group by on other columns

Below is the structure of table I have: -
Table T1
C1 C2 C3
----------
X P A
X P B
Y Q C
Y Q D
Desired output: -
C1 C2 C3
------------
X P A,B
Y Q C,D
Note: - I know i can do the same with For XML('') with group by on C1 and C2, but the main problem in my case is that the table T1 here must be a physical table object (either permanent or temp or table var or CTE) in DB. But in my case it's a derived table and when i am using the below query it's saying invalid object.
In my case it's not good to replace the derived table with temp# tables or fixed tables or even with CTE or table variable because it will take a great effort.
SELECT
b.C1, b.C2, Stuff((',' + a.C3 from t1 a where a.c1 = b.c1 for XML PATH('')),1,1,'') FROM
T1 b group by b.c1,b.c2
I did not have T1 as fixed table. Please consider it as derived table only.
I need the solution with existing derived table.
Please help.
Below is the query with derived table: -
Please consider this only as a demo query. It's not as simple as given below and a lot of calculations have done to get the derived tables and 4 levels of derived tables have been used.
SELECT C1, C2, Stuff((',' + a.C3 from A B where a.c1 = b.c1 for XML PATH('')),1,1,'')
FROM
(
SELECT C1, C2, C3 FROM T1 WHERE C1 IS NOT NULL--and a lot of calculation also
)A
Please mind that T1 is not just below one step, in my case T1 the actual physical table is 4 level downs by derived tables.
If you can post the query the produces derived table, we can help you work it out, but as of the moment try substituting table1 with the derived query.
;WITH Table1
AS
(
SELECT C1, C2, C3 FROM T1 WHERE C1 IS NOT NULL--and a lot of calculation also
)
SELECT
C1,C2,
STUFF(
(SELECT ',' + C3
FROM Table1
WHERE C1 = a.C1 AND C2 = a.C2
FOR XML PATH (''))
, 1, 1, '') AS NamesList
FROM Table1 AS a
GROUP BY C1,C2
SQLFiddle Demo