SQL append column at the bottom of another column - sql

What is the best way to append a column at the bottom of another column? So it would look something like this:
column_a column_b
a e
f k
c m
new_column
a
f
c
e
k
m
All i can really find is answers on how to merge two column into one and this is with CONCAT() but nothing about pasting two column ontop of each other.

If you want to keep the order, you could use something like this.
with col_a as (select 'a' as column_a union select 'f' union select 'c'),
col_b as (select 'e' as column_b union select 'k' union select 'm')
select 1 as num_order,
column_a
from col_a
union all
select 2 as num_order,
column_b
from col_b
order by num_order;
Yields:
1,a
1,c
1,f
2,e
2,k
2,m
If the order is irrelevant you can omit the num_order attribute.

Related

How do I find all values where all rows associated with that value meet a condition?

I have a table in SQL that is structured as follows:
Name Value1 Value2
A .2 .3
A .1 .05
A .5 .3
B .2 .4
B .1 .08
C .3 .4
C .2 .5
C .1 .3
How do I get all the Names where Value1 is less than Value2 for every row associated with a Name? In the example above, I would only want to pull out Name C.
I read this article: Select in MySQL where all rows meet a condition
but I don't think this applies to my problem, as this solution assumes you are comparing a row to fixed value.
A variant on some of the other answers, also using conditional aggregation:
SELECT Name
FROM yourTable
GROUP BY Name
HAVING SUM(CASE WHEN value1 >= value2 THEN 1 ELSE 0 END) = 0;
The above query asserts that each matching name group does not have any record for which value1 is greater than or equal to value2.
You can use group by and having:
select name
from t
group by name
having count(*) = sum(case when value1 < value2 then 1 else 0 end);
There are other ways to phrase this, such as:
select distinct name
from t
where not exists (select 1 from t t2 where t2.name = t.name and t2.value2 >= t2.value1);
Or:
select name
from t
except
select name
from t
where value2 >= value1;
You can get desired result with in clause
declare #table table (name varchar(10), value1 float, value2 float)
insert #table
select 'A', '0.2', '.3'
union all
select 'A' , '.1', '.05'
union all
select 'A', '.5', '.3'
union all
select 'B', '.2', '.4'
union all
select 'B', '.1' , '.08'
union all
select 'C', '.3' , '.4'
union all
select 'C', '.2' , '.5'
union all
select 'C' , '.1' , '.3'
Use In Clause where value1<value2
select * from #table where value1<value2
and name not in ( select name from #table where value1>value2)
You can use EXIST to check if the value exist in your desired condition wherein all rows by certain name have value2 greater than value1.
SELECT *
FROM TableName a
WHERE EXISTS (SELECT 1
FROM TableName b
WHERE a.name = b.Name
GROUP BY b.name
HAVING COUNT(case when b.value1 < b.value2 THEN 1 END) = COUNT(*))
Here's a Demo.
This will display all rows for the valid name. However, check other answer if you only want to display distinct name.

How can I acces the output from the first select statement

I have a table Like this
Col1 | Col2
-----------
a | d
b | e
c | a
Now I want to create an statement to get an output like this:
First| Second
-------------------
a | Amsterdamm
b | Berlin
c | Canada
...
So far I have this consturct what is not working
SELECT *
FROM(
SELECT DISTINCT
CASE
when Col1 IS NULL then 'NA'
else Col1
END
FROM Table1
UNION
SELECT DISTINCT
CASE
when Col2 IS NULL then 'NA'
else Col2
END
FROM Table1
) AS First
,
(
SELECT DISTINCT
when First= 'a' then 'Amsterdam'
when First= 'b' then 'Berlin'
when First= 'c' then 'Canada'
) AS Second
;
can you help me with that
Sorry I have to edit my question to be more specific.
Not as familiar with DB2... I'll lookup if it has a concat function in a sec... and it does.
SELECT First, case when first = 'a' then
concat('This is a ',first)
case when first = 'b' then
concat('To Be or not to ',first)
case else
concat('This is a ',first) end as Second
FROM (
SELECT coalesce(col1, 'NA') as First
FROM Table
UNION
SELECT coalesce(col2, 'NA')
FROM table) SRC
WHERE first <> 'NA'
What this does is generate a single inline view called src with a column called first. If col1 or col2 of table are null then it substitutes NA for that value. It then concatenates first and the desired text excluding records with a first value of 'NA'
Or if you just create an inline table with the desired values and join in...
SELECT First, x.b as Second
FROM (
SELECT coalesce(col1, 'NA') as First
FROM Table
UNION
SELECT coalesce(col2, 'NA')
FROM table) SRC
INNER JOIN (select a,b
from (values ('a', 'This is a'),
('b', 'To B or not to' ),
('c', 'I like cat whose name starts with')) as x(a,b)) X;
on X.a = src.first
WHERE first <> 'NA'
Personally I find the 2nd option easier to read. Though if you have meaning for a,b,c I would think you'd want that stored in a table somewhere for additional access. In code seems like a bad place to store data like this that could change.
Assuming you want
a this is a a
b this is a b
c this is a c
d this is a d
e this is a e
thanks to xQbert
I could solve this problem like this
SELECT FirstRow, concat
(
CASE FirstRow
WHEN 'AN' then 'amerstdam'
WHEN 'G' then 'berlin'
ELSE 'NA'
END, ''
) AS SecondRow
FROM(
Select coalesce (Col1, 'NA') as FirstRow
FROM Table1
UNION
Select coalesce (Col2, 'NA')
FROM Table1) SRC
WHERE FirstRow <> 'NA'
;

Oracle: Get All Rows Except One

I am stuck with a simple query. What i want is to get all rows except one Kindly have a look at the following data.
COL_A COL_B
B D
B (null)
B C
G D
G (null)
G C
I want to get all rows except but B C. Kindly have a look at the sqlfiddle
I have tried to get the rows by anding col_A <> 'B' and col_B <> 'C' but it's not anding the operation. Your help will be much appreciated.
Thanks
One possible solution. Maybe not the most elegant:
select req_for col_A, doc_typ col_B
from a
where (req_for IS NULL OR doc_typ IS NULL)
OR (req_for,doc_typ)
NOT IN (select 'B','C' from dual);
Try
where not(col_A = 'B' and col_B = 'C')
or
where col_A <> 'B' or col_B <> 'C'
Your problem is the NULL values. Here is a concise way of expressing this in Oracle:
where (col_A || col_B) <> 'BC'
Oracle treats NULL values as the empty string in string concatenation.
Ah, negatives. Always causing trouble. With a SQL query like this you have to think about what you want to INCLUDE, not what you want to EXCLUDE.
If you do where nvl(doc_typ,'NA') <> 'C' and nvl(req_for, 'NA') <> 'B';, you aren't including any rows with doc_type of C, and you aren't including any rows with req_for of B.
You want to do where nvl(doc_typ,'NA') <> 'C' or nvl(req_for, 'NA') <> 'B';. This way a doc_type of C will still be included, as long as its req_for isn't also B.
Could you not just remove the unwanted row:
select req_for col_A, doc_typ col_B from a
where NOT (NVL(doc_typ,'NA') = 'C' AND nvl(req_for,'NA') = 'B');
select req_for col_A, doc_typ col_B from a
where req_for||doc_typ != 'BC';
select req_for col_A, doc_typ col_B from a
where case when req_for = 'B' and doc_typ='C' then 0 else 1 end > 0

How to write query to return value regardless of existance?

Given this:
with data_row as (select 1 as col_1 from dual)
select 'Y' as row_exists from dual where exists
(select null
from data_row
where col_1 in (2,1))
How can I get this?
Col_1 Row_exists
--------------------
1 Y
2 N
In order to get a row of output, you need a row of input. You want to get the second row with a "2", but there is no table with that value.
The approach is to generate a table that has the values that you want, and then use left outer join to find which match:
with data_row as (
select 1 as col_1
from dual
),
what_i_care_about as (
select 1 as col from dual union all
select 2 from dual
)
select wica.col,
(case when dr.col_1 is NULL then 'N' else 'Y' end) as row_exists
from what_i_care_about wica left outer join
data_row dr
on wica.col = dr.col_1;
You cannot do directly what you want -- which is to create a row for each missing value in the in list. If you have a lot of values and they are consecutive numeric, then you can use connect by or a recursive CTE to generate the values.

SQL Server, View using multiple select statements

I've banging my head for hours, it seems simple enough, but here goes:
I'd like to create a view using multiple select statements that outputs a Single record-set
Example:
CREATE VIEW dbo.TestDB
AS
SELECT X AS 'First'
FROM The_Table
WHERE The_Value = 'y'
SELECT X AS 'Second'
FROM The_Table
WHERE The_Value = 'z'
i wanted to output the following recordset:
Column_1 | Column_2
'First' 'Second'
any help would be greatly appreciated!
-Thanks.
A union might be what you want, but keep in mind you need to have the exact same columns so you would need to add a null column to each select.
SELECT X AS 'First', Null as 'Second'
FROM The_Table
WHERE The_Value = 'y'
Union
SELECT null as 'First', X AS 'Second'
FROM The_Table
WHERE The_Value = 'z'
This will combine the two results and give you only the unique combinations. My guess is that this isn't what you are looking for.
Is there a reason why you can't accomplish this in one query or do some subqueries perhaps? Maybe you can provide a more concrete example.
if you want this:
Column_1 | Column_2
'First' null
null 'Second'
you can use the UNION like suggested in the other answers, but if you really want then on the same row like in your question:
Column_1 | Column_2
'First' 'Second'
try something like this:
CREATE VIEW dbo.TestDB
AS
SELECT
dt.First,dt2.Second
FROM (SELECT
X AS 'First',ROW_NUMBER() OVER(ORDER BY X) AS RowNumber
FROM The_Table
WHERE The_Value = 'y'
) dt
LEFT OUTER JOIN (SELECT
X AS 'Second',ROW_NUMBER() OVER(ORDER BY X) AS RowNumber
FROM The_Table
WHERE The_Value = 'z'
) dt2 ON dt.RowNumber=dt2.RowNumber
go
I'm not sure how to join the tables, no info about PKs or how to join them is given.
Untested
CREATE VIEW dbo.TestDB
AS
SELECT CASE The_Value when 'y' then x else NULL END AS 'First',
CASE The_Value when 'z' then x else NULL END AS 'Second'
FROM The_Table
WHERE The_Value in( 'y','z')