SQL comparing all values in a many-one table - sql

I have a table as follows
column1 column2
a 1
a 2
b 2
I need to write an sql query that will go through the table and return me all column 2 values that have both a and b in column 1.

Try this:
SELECT column2
FROM mytable
WHERE column1 IN ('a', 'b')
GROUP BY column2
HAVING COUNT(DISTINCT column1) = 2

Try this:
SELECT column1, column2, ROW_NUMBER()OVER(PARTITION BY column1 Order by column1 )as rowCounts into #tmp2
FROM #tmp
SELECT column2 FROM #tmp2 WHERE rowCounts = 1

Related

Subtract 2 rows using case statement in SQL Server 2008

My data is like below, it's in a single table
Column1 Column2
abc 100
abc 200
Now I need like below
abc 100 //here 200-100
I am banging my head on how to achieve this.
I have tried to use the row_number and then subtract using case statement like
Select
column1,
sum(
case when rownum=1
then column2
end
-
case when rownum=2
then column2
end
)
from table
group by column1
But this is giving me null.
Assuming there is no attribute which can define row ordering -
;with cte as(
select
row_number() over (order by (select null)) as IndexId,
Column1,
Column2
from #xyz
)
select sum(case when IndexID=1 then (-1 * Column2) else Column2 end), Column1
from cte
group by Column1
Input data-
declare #xyz table(Column1 varchar(10),Column2 int)
insert into #xyz
select 'abc' ,100 union all
select 'abc' ,200
Assuming you have an attribute rownum in table which is always 1 or 2 (it can be generated by some row_number() as you suggest in question, according to any order that is suitable for you)
Column1 Column2 Rownum
------------------------
abc 100 1
abc 200 2
then you can simply use
Select
column1,
sum(
case when rownum=1
then column2
else -column2
end
)
from table
group by column1
It performs a sum of the Column2 per Column1, however, in the row having rownum = 2 the Column2 value is negated. Therefore in our example you end up with 100 + (-200) = -100
You could do:
select column1, max(column2) - min(column2)
from t
group by column1;
Here is a short form of the answer above if you care:
SELECT
column1,
SUM(IIF(rownum=1,column2,-column2))
FROM table
GROUP BY column1

How to combine multiple columns into one column?

I'm writing a query and want the results in one column
My current results return like this
Column1 Column2 column3
1 A CAT
I want the results to return like this
Column1
1
A
CAT
SELECT Column1 FROM TableName
UNION ALL
SELECT Column2 FROM TableName
UNION ALL
SELECT Column3 FROM TableName
If you don't want duplicate values, use UNION instead of UNION ALL.
You can also do this using UNPIVOT operator
SELECT Column123
FROM
(
SELECT Column1, Column2, Column3
FROM TableName
) AS tmp
UNPIVOT
(
Column123 FOR ColumnAll IN (Column1, Column2, Column3)
) AS unpvt;
https://www.w3schools.com/sql/sql_union.asp
https://www.mssqltips.com/sqlservertip/3000/use-sql-servers-unpivot-operator-to-help-normalize-output/
The answer is.. it depends..
If the number of columns are unknown.. then use unpivot as UZI has suggested
if you know all columns and is a small finite set..
you can simply go
Select
column1
from table
union all
select column2
from table
union all
select column3
from table
The Cartesian product of the T table with derived table of 3 rows.(each row of #t is presented 3 times, for а=1 and а=2 and а=3). For the first case we take value from Column1,
and for the second - from Column2 and for the Third - from Column3.
Here, certainly, there is both union and join but, in my opinion, the title's question means single scanning the table.
CREATE TABLE #t (Column1 NVARCHAR(25),Column2 NVARCHAR(25), column3 NVARCHAR(25))
INSERT INTO #t
SELECT '1','A','CAT'
SELECT
CASE a WHEN 1 THEN Column1 WHEN 2 THEN Column2 ELSE column3 END col
FROM #t, (SELECT 1 a UNION ALL SELECT 2 UNION ALL SELECT 3) B
DROP TABLE #t

Select statement for Oracle SQL

I have a table say,
column1 column2
a apple
a ball
a boy
b apple
b eagle
b orange
c bat
c ball
c cork
Now I would like to fetch column1 based on the rows that doesn't contain 'apple' and also ignore values in column1 if any of the rows have 'apple' in it. So in the table above only 'C' must be retured.
I am kind of new to Oracle SQL and I know Select column1 from table where column2 != 'apple' will not work. I need some help with this please.
You could use DISTINCT with NOT IN in following:
QUERY 1 using NOT IN
select distinct col1
from t
where col1 not in (select col1 from t where col2 = 'Apple')
QUERY 2 using NOT EXISTS
As per #jarlh comment you could use NOT EXISTS in following:
select distinct col1
from #t t1
where not exists (select 1 from #t t2 where col2 = 'Apple' and t1.col1 = t2.col1)
SAMPLE DATA
create table t
(
col1 nvarchar(60),
col2 nvarchar(60)
)
insert into t values
('a','apple')
,('a','ball')
,('a','boy')
,('b','apple')
,('b','eagle')
,('b','orange')
,('c','bat')
,('c','ball')
,('c','cork')
Assuming that column1 is NOT NULL you could use:
SELECT DISTINCT t.column1
FROM table_name t
WHERE t.column1 NOT IN (SELECT column1
FROM table_name
WHERE column2 = 'apple');
LiveDemo
To get all columns and rows change DISTINCT t.column1 to *.
Select * from tbl
Left join (
Select column1 from tbl
Where column2 like '%apple%'
Group by column1
) g on tbl.colum1 = g.column1
Where g.column1 is null
Seems to me that you need to find a summary of all colum1 values that have any reference to apple. Then list the rows that have no match to the summary list (g)
If I understand well, you need the values af column1 such that in your table does not exist a row with the same value of column1 and 'apple' in column2; you can translate this in SQL with:
Select column1
from your_table t
where not exists (
select 1
from your_table t2
where t2.column1 = t1.column1
and t2.column2= 'apple'
)
This is only one of the possible ways to get your result, soyou can rewrite it in many ways; I believe this way of writing is similar enough to the logics to clearly explain how a logic could be written in plain SQL.

SQL Count/Sum displaying column as rows

I have a table with 4 bit columns
I need to create a report that will show the total of all "true" values for each column but I need the column names to return as a row.
For examples, the table will contain:
Column1 Column2 Column3
1 1 0
0 1 0
1 1 0
The result should be:
Category Value
Column1 2
Column2 3
Column3 0
The table has other columns, I just need specific ones
Thanks
I don't know if there are other approaches, but the following should work:
select 'Column1' as "Category", sum(column1) as "Value" from my_table union
select 'Column2', sum(column2) from my_table union
select 'Column3', sum(column3) from my_table
Here's a SQLFiddle for it.
You can try UNPIVOT on the table (this is for SQL Server)
create table Test (Column1 bit, Column2 bit, Column3 bit)
insert into Test values (1,1,0)
insert into Test values (0,1,0)
insert into Test values (1,1,0)
SELECT Value, sum(Vals)
FROM
(CONVERT(INT, Column1) Column1, CONVERT(INT, Column2) Column2, CONVERT(INT, Column3) Column3
FROM Test) p
UNPIVOT
(Vals FOR Value IN
(Column1, Column2, Column3)
)AS unpvt
GROUP BY Value
PIVOT/UNPIVOT documentation
http://sqlfiddle.com/#!6/957c6/1/0
Try this:
select
category = "column1", value = sum (convert(int,col1)) from MyTable1
union
select
category = "column2", value = sum (convert(int,col2)) from MyTable1
union
select
category = "column3", value = sum (convert(int,col3)) from MyTable1

How to access the value of a function generated column in SQL

I have the following SQL
select count(*) col, column1, column2, column3 from TempTable
group by column1, column2, column3
order by 1 desc
so the column generated by the count will return a number and there are 17 rows that do not have the number 1 (duplicate rows as columns 1, 2 and 3 are primary keys) and i want to delete any that have the count greater than 1?
You can use the having-clause:
select count(*) col, column1, column2, column3
from TempTable group by column1, column2, column3
having count(*) > 1
order by 1 desc
To delete:
delete tt
from TempTable tt
inner join (select count(*) col, column1, column2, column3
from TempTable group by column1, column2, column3
having count(*) > 1) tmp
on tmp.column1 = tt.column1
and tmp.column2 = tt.column2
and tmp.column3 = tt.column3
First you insert the data in temporary table:
select count(*) col, column1, column2, column3
into #temp
from TempTable group by column1, column2, column3 order by 1 desc
Then, you delete the data, and insert it from the #temp table:
delete from TempTable
go
insert into TempTable select column1, column2, column3 from #temp
go