How to add a column to a row in a select - sql

Say I have this table
| Col |
-------
| ABC |
| DEF |
What query should I write to obtain this result (not literally this result, but a general way to do that)?
| Col | Col2 |
--------------
| ABC | 0 |
| ABC | 1 |
| DEF | 0 |
| DEF | 1 |

Unless I'm missing something, this should give you the results you're looking for:
Select Col, Col2
From YourTable
Cross Join (Select 0 As Col2 Union Select 1 As Col2) X
Order By Col, Col2

I would guess that you want to pair two columns, for each combination. Your question is vague and not specific to a problem. That's my assumption.
I guess this query could do:
Select Table1.Col1, Table2.Col2 from Table1 LEFT JOIN Table2 on 1=1
This way, you pair up every row from table1 with every row from table2.
Edit, without table2:
Select Table1.Col1, Constructed.Col1 from Table1 LEFT JOIN
(Select 1 as Col1 UNION Select 2 as Col1 UNION
Select 7 as Col1 UNION Select 14 as Col1) Constructed on 1=1

Can you test query, is this what you want?
select * from
(select col1, 0 b from table) table1
union all (select col1, 1 b from table) order by 1;

Related

SQL - Create a formatted ouput with placeholder rows

For reasons of our IT department, I am stuck doing this entirely within an SQL query.
Simplified, I have this as an input table:
And I need to create this:
And I am just not sure where to start with this. In my normal C# way of thinking its easy. Column1 is ordered, if the value in Col1 is new, then add a new row to the output and put the contents in column1 in the output. Then, whilst the contents of the input Column1 is unchanged, keep adding the contents of column2 to new rows.
In SQL... nope, I just cannot see the right way to start!
This is a presentation issue that can be easily done in the application or presentation layer. In SQL this can be clunky. The goal of a database is not to render a UI but to store and retrieve data fast and also efficiently, in order to serve as many clients as possible with the same hardware and software resources constraints.
The query that could do this can look like:
with
y as (
select col1, row_number() over(order by col1) as r1
from (select distinct col1 as col1 from t) x
),
z as (
select
t.col1, y.r1, t.col2,
row_number() over(partition by t.col1 order by t.col2) as r2
from t
join y on y.col1 = x.col1
)
select col1, col2
from (
select col1, null as col2, r1, 0 from y
union all
select null, col2, r1, r2 from z
) w
order by r1, r2
As you see, it looks clunky and bloated.
You need a header row for each group which will consist of col1 and null and all the rows of the table with null as col1.
You can do it with UNION ALL and conditional sorting:
select
case when t.col2 is null then t.col1 end col1,
t.col2
from (
select col1, col2 from tablename
union all
select distinct col1, null from tablename
) t
order by
t.col1,
case when t.col2 is null then 1 else 2 end,
t.col2
See the demo (for MySql but it is standard SQL).
Results:
| col1 | col2 |
| ---- | ----- |
| SetA | |
| | BH101 |
| | BH102 |
| | BH103 |
| SetB | |
| | BH201 |
| | BH202 |
| | BH203 |
I agree, formatting should be done outside of SQL, but if you have no choice, here is some SQL Server code that will generate your output
select *
from (
select top 100
case
when col2 is null then ' '+col1
else '' end as firstCol,
IsNull(col2,'') as Col2
from dbo.test t1
group by col1,col2 with rollup
order by col1,col2
) x
where x.firstcol is not null

sql - Only want rows with NULL in column if it isn't defined somewhere else as well

I have a table with possible NULL values in a column. I need to return the NULL values, but only if it isn't also defined somewhere else. Below, I want row F, but I do not want row B. We have some automation that attempts something but also has a fail over. We need to identify when both tries fail.
Column 1 | Column 2
A | 1
B | 1
B | null
C | 2
C | 1
D | 1
E | 2
F | null
F | null
G | 2
Simply do aggregation :
select col1, null as col2
from table t
group by col1
having max(col2) is null;
You can use not exists:
select t.*
from mytable t
where not exists (
select 1
from mytable t1
where t1.column1 = t.column1 and t1.column2 is not null
)
Or you can use window functions:
select column1, column2
from (
select t.*, max(column2) over(partition by column1) max_column2
from mytable t
) t
where max_column2 is null

Fetch duplicate rows from a table

I have the following table
Col1 | Col2
2 | jim
2 | jam
3 | raw
3 | cooked
3 | boiled
5 | none
6 | yum
So in this table I want to fetch records which have multiple value in col1 like:
Col1 | Col2
2 | jim
2 | jam
3 | raw
3 | cooked
3 | boiled
This should work for you, an alternative to using EXISTS:
select t.*
from <table> t
cross apply (select 1 ex
from <table> t2
where t2.Col1=t.Col1
group by t2.Col1
having count(t2.Col1) > 1) tmp
Use exists:
select col1, col2
from t
where exists (select 1
from t t2
where t2.col1 = t.col1 and t2.col2 <> t.col2
);
Use this query
select *
from t
where col1 in
( select col1
from t
group by col1
having count(*) > 1
)

Rotate one column and Select it comma seperated [duplicate]

This question already has answers here:
Inner Join Two Table, aggregating varchar fields
(2 answers)
Closed 8 years ago.
I have a table like this:
PK | COL1 | COL2
----------------
1 | A | a
2 | B | b
3 | C | c
4 | A | d
5 | A | e
6 | B | f
7 | C | g
8 | C | h
and I want to do an Select that I get the following result
COL1 | COL2
---------------
A | a,d,e
B | b,f
C | c,g,h
As I understand SQL at the moment I don't know how to do this without "programing" something extra e.q. with PL/SQL
But i search for an DBMS independent solution as good as it can be DBMS independent.
This is an Oracle (11.2) solution:
select col1,
listagg(col2, ',') within group (order by col1) as col2
from the_table
group by col1;
As you need this for other DBMS as well, this would be the Postgres solution:
select col1,
string_agg(col2, ',' order by col1) as col2
from the_table
group by col1;
For MySQL this would be:
select col1,
group_concat(col2 ORDER BY col1 SEPARATOR ',') as col2
from the_table
group by col1;
For a SQL Server solution, see Vijaykumar's answer.
try this !!
SELECT [col1],
SUBSTRING(d.col2,1, LEN(d.col2) - 1) col2
FROM
(
SELECT DISTINCT [col1]
FROM table1
) a
CROSS APPLY
(
SELECT [col2] + ', '
FROM table1 AS b
WHERE a.[col1] = b.[col1]
FOR XML PATH('')
) d (col2)

Update unique rows in SQL

I have a table
id | col1 | col3| col4
1 | x | r |
2 | y | m |
3 | z | p |
4 | x | r |
i have to update all unique rows of this table
i.e
id | col1 | col3| col4
1 | x | r | 1
2 | y | m | 1
3 | z | p | 1
4 | x | r | 0
i can fetch unique rows by
select distinct col1,col2 from table
.But how can i identify these rows in order to update them.Please help.
You can use the group by to pick unique result:
SELECT MIN(ID) AS ID FROM TABLE GROUP BY COL1, COL3;
id | col1 | col3
1 | x | r
2 | y | m
3 | z | p
Then
UPDATE TABLE SET col4 = 1 WHERE ID IN (SELECT MIN(ID) FROM TABLE GROUP BY COL1, COL3);
Restriction is that the id column should be unique.
If it is a small enough table, here is what you can do
Step 1: Update everything to 1
Update Table Set Col4 = 1
Step 2: Update all dups to 0 (OTTOMH)
Update Table
Set Col4 = 0
From
(
Select Col1, Min (Id) FirstId
From Table
Group By Col1
Having Count (*) > 1
) Duplicates
Where Table.Col1 = Duplicates.Col1
And Table.Id <> Duplicates.FirstId
You can also try:
UPDATE test
SET col4 = 1
WHERE id IN
(
SELECT t1.id
FROM table_name t1
LEFT JOIN table_name t2
ON t2.id < t1.id
AND t2.col1 = t1.col1
AND t2.col3 = t1.col3
WHERE t2.id IS NULL
)
One more slightly convoluted option, to set both 0 and 1 values in one hit:
update my_table mt
set col4 = (
select case when rn = 1 then 1 else 0 end
from (
select id,
row_number() over (partition by col1, col3 order by id) as rn
from my_table) tt
where tt.id = mt.id);
4 rows updated.
select * from my_table order by id;
ID COL1 COL3 COL4
---------- ---- ---- ----------
1 x r 1
2 y m 1
3 z p 1
4 x r 0
This is just using row_number() to decide which of the unique combinations is first, arbitrarily using the lowest id, assigning that the value of one, and everything else zero.