SQL Query Syntax Error using select & <> with 2 columns - sql

I got a table with 2 columns here.
| column1 | column2 |
| A | 1 |
| B | 1 |
| C | 2 |
| D | 1 |
I'm trying to execute a SELECT query that:
Selects a value FROM Column 2 WHILE Column 2 doesn't have the same value in a row which has Column 1 = "A"
SELECT column2 from mytable and column2 <> (SELECT * FROM mytable where column1 = 'A');
Basically I'm trying to execute a query that returns column1 values only when column2 is valued at "2" here.
But the project I'm making will be having column2 values random so I should use only columns names
Sorry if that's too confusing!

The subquery of your query returns multiple values. So you have to use NOT IN instead of <>:
SELECT column2
FROM mytable
WHERE column2 NOT IN (SELECT column2 FROM mytable WHERE column1 = 'A');

use corelated subquery
select t1.* from mytable t1
where not exists ( select 1 from mytable t2 where t2.column2=t1.column2 and column1='A')
or use not in
select t1.* from table_name t1 where t1.column2 not in ( select column2 from table_name where column1='A')

You could also use a join, for example:
select t1.column2
from mytable t1 left join
(select distinct t2.column2 from mytable t2 where t2.column1='A') t3 on t1.column2=t3.column2
where t3.column2 is null

Related

Query for finding duplicate records where 2nd field is different

Probably very simple but given data of
TableA
FIELD1 | FIELD2
A | 1
A | 1
A | 2
B | 3
B | 3
C | 4
C | 5
How can I find the duplicate of Field 1 where Field 2 is different.
e.g from data above I want to return records 3 (A2) and 6 (C5)
Thanks in advance
You can use the following:
SELECT t1.* FROM table_name t1 INNER JOIN (
SELECT FIELD1, MIN(FIELD2) AS FIELD2
FROM table_name
GROUP BY FIELD1
) t2 ON t1.FIELD1 = t2.FIELD1 AND t1.FIELD2 <> t2.FIELD2
demo on dbfiddle.uk
You can use exists:
select a.*
from tableA a
where a.field2 > (select min(a2.field2)
from tableA a2
where a2.field1 = a.field1
);
You could also use window functions:
select a.*
from (select a.*,
min(a.field2) over (partition by field1) as min_field2
from tableA a
) a
where field2 > min_field2;

SQL: KEEP Unique value of C1 with Highest value in C2

In my two columns of data I would like to keep only the unique values of ColumnOne that have the highest value in ColumnTwo.
For example
ColumnOne ColumnTwo
2 6
3 2
7 8
2 7
3 4
7 3
I would like the results:
ColumnOne ColumnTwo
2 7
3 4
7 8
You can do this with a group by statement:
select Column1, max(Column2)
from your_table
group by Column1
delete t1
from myTable t1
left join (select t2.Column1, max(t2.Column2) maxColumn2
from myTable t2
group by t2.Column1) tMax
on t1.Column1 = tMax.Column1
and t1.Column2 = tMax.maxColumn2
where tMax.Column1 is null
The below query will help you to accomplish your output for tables with huge no. of records:
create table table1_new as (select * from table1) with no data;
insert into table1_new
select columnone, max(columntwo) over(partition by columnone) from table1 group by columnone;
Validate data and then interchange table names:
drop table table1;
rename table1_new to table1;

Get groups that are exactly equal to a table

I have a query that groups easily. I need to get the groups that have exactly the same records to another table (relationship).
I'm using ANSI-SQL under SQL Server, but I accept an answer of any implementation.
For example:
Table1:
Id | Value
---+------
1 | 1
1 | 2
1 | 3
2 | 4
3 | 2
4 | 3
Table2:
Value | ...
------+------
1 | ...
2 | ...
3 | ...
In my example, the result is:
Id |
---+
1 |
How imagined that it could be the code:
SELECT Table1.Id
FROM Table1
GROUP BY Table1.Id
HAVING ...? -- The group that has exactly the same elements of Table2
Thanks in advance!
You can try the following:
select t1.Id
from Table2 t2
join Table1 t1 on t1.value = t2.value
group by t1.Id
having count(distinct t1.value) = (select count(*) from Table2)
SQLFiddle
To get the same sets use an inner join:
SELECT Table1.Id
FROM Table1
INNER JOIN table2 ON table1.id=table2.id
GROUP BY Table1.Id
HAVING ...? --
CREATE TABLE #T1 (ID INT , [Values] INT) INSERT INTO #T1 VALUES (1,1),(1,2),(1,3),(2,4),(2,5),(3,6)
CREATE TABLE #T2 ([Values] INT) INSERT INTO #T2 VALUES (1),(2),(3),(4)
SELECT * FROM #T1
SELECT * FROM #T2
SELECT A.ID
FROM
( SELECT ID , COUNT(DISTINCT [Values]) AS Count FROM #T1
GROUP BY ID
) A
JOIN
(
SELECT T1.ID, COUNT(DISTINCT T2.[Values]) Count
FROM #T1 T1
JOIN #t2 T2
ON T1.[Values] = T2.[Values]
GROUP BY T1.ID
) B
ON A.ID = B.ID AND A.Count = B.Count

Within a SQL Server view - how to combine multiple column results into one column

I have a SQL Server database with the following 2 tables:
I have created a view with the following query and results:
My question is what query would bring the (3) ID columns in 'Table2' into one master ID List to where the final result would look like this:
ID Table1ID
test1 1
test1 4
test2 1
test2 2
test3 1
test3 2
test3 3
Note: here is the view as shown above:
SELECT
dbo.Table1.Description, Table2_1.ID AS Table2ID_1, Table2_2.ID AS Table2ID_2,
dbo.Table2.ID AS Table2ID_3
FROM
dbo.Table1
LEFT OUTER JOIN
dbo.Table2 ON dbo.Table1.ID = dbo.Table2.Table1ID3
LEFT OUTER JOIN
dbo.Table2 AS Table2_2 ON dbo.Table1.ID = Table2_2.Table1ID2
LEFT OUTER JOIN
dbo.Table2 AS Table2_1 ON dbo.Table1.ID = Table2_1.Table1ID1
My suggestion would be to UNPIVOT the data in Table2 so you can easily join on the data, then you can return the table1 description and the table2 id. The UNPIVOT portion of this query using CROSS APPLY:
select col, value, t2.Id
from table2 t2
cross apply
(
select 'table1id1', table1id1 union all
select 'table1id2', table1id2 union all
select 'table1id3', table1id3
) c (col, value);
See SQL Fiddle with Demo. This gives a result:
| COL | VALUE | ID |
---------------------------
| table1id1 | 1 | 1 |
| table1id2 | 2 | 1 |
| table1id3 | 3 | 1 |
| table1id1 | 2 | 2 |
| table1id2 | 3 | 2 |
| table1id3 | (null) | 2 |
| table1id1 | 3 | 3 |
Now that you have the data in rows, you can easily join on the value column to return the id:
select t1.description,
d.id
from table1 t1
inner join
(
select col, value, t2.Id
from table2 t2
cross apply
(
select 'table1id1', table1id1 union all
select 'table1id2', table1id2 union all
select 'table1id3', table1id3
) c (col, value)
) d
on t1.id = d.value
order by t1.description, d.id;
See SQL Fiddle with Demo
If you really want to use UNPIVOT, then you can use the following which doesn't join on each table multiple times to get the result:
select t1.description, t2.id
from table1 t1
inner join
(
select id, col, value
from
(
select id, [Table1ID1], [Table1ID2], [Table1ID3]
from table2
) d
unpivot
(
value for col in ([Table1ID1], [Table1ID2], [Table1ID3])
) unpiv
) t2
on t1.id = t2.value
order by t1.description, t2.id;
See SQL Fiddle with Demo.
The UNPIVOT and the CROSS APPLY is doing the same thing as a UNION ALL query:
select t1.description, t2.id
from table1 t1
inner join
(
select id, 'table1id1' col, table1id1 value
from table2
union all
select id, 'table1id2' col, table1id2
from table2
union all
select id, 'table1id3' col, table1id3
from table2
) t2
on t1.id = t2.value
order by t1.description, t2.id;
See SQL Fiddle with Demo
Microsoft SQL Server 2005 and higher support an UNPIVOT statement making the CROSS APPLY unnecessary.
SELECT Description AS [ID], Table1ID
FROM (SELECT Table1.Description, Table2_1.ID AS Table2ID_1, Table2_2.ID AS Table2ID_2, Table2.ID AS Table2ID_3
FROM Table1 LEFT OUTER JOIN
Table2 ON Table1.ID = Table2.Table1ID3 LEFT OUTER JOIN
Table2 AS Table2_2 ON Table1.ID = Table2_2.Table1ID2 LEFT OUTER JOIN
Table2 AS Table2_1 ON Table1.ID = Table2_1.Table1ID1) AS pvttbl
UNPIVOT ( Table1ID FOR ID IN (Table2ID_1, Table2ID_2, Table2ID_3)) AS unpvttbl
ORDER BY Description, Table1ID
See Using PIVOT and UNPIVOT on MSDN.

Resolved: Query that returns the output where one column matches all the values in another column

Using oracle developer, I've run a query that results in the following table. But I only want the results where column1 matches all the values columns 2 (3,4,8). So the output would be 2, 3, but not 4. I'm sure there is a way to bring this result about without hard coding it? I'm thinking its some sort of self-join?
select column1, column2
from table1
where column1 in (
select column1
from table2
where depth >= 100)
order by column2;
Output:
column1 column2
3 2
8 2
4 2
3 3
4 3
8 3
4 4
Table2
Column1 Area_Name Depth
1 Lake 40
2 River 50
3 Ocean 150
4 Cliff 150
5 Mountain 90
6 Construction 60
7 Building 50
8 Random 100
9 Also Random 50
10 Another one 80
Needed output:
column2
2
3
Ok, this is what I was looking for:
SELECT table1.column1
FROM table1
INNER JOIN table2
ON table1.column2 = table2.column2
WHERE table2.depth >= 100
GROUP BY boat_id
HAVING COUNT(*) >= (
select count(*)
from table2
where depth >= 100);
UPDATED
WITH qry AS (
SELECT column1, column2
FROM table1
WHERE column1 IN (
SELECT column1
FROM table2
WHERE depth >= 100)
)
SELECT t1.column2
FROM qry t1 LEFT JOIN qry t2
ON t1.column1 = t2.column1 AND t1.column2 = t2.column2
GROUP BY t1.column2
HAVING COUNT(*) = (SELECT COUNT(DISTINCT column1) FROM qry)
ORDER BY t1.column2
Output:
| COLUMN2 |
-----------
| 2 |
| 3 |
SQLFiddle