Add row to query result using select - sql

Is it possible to extend query results with literals like this?
select name from users
union
select name from ('JASON');
or
select age, name from users
union
select age, name from (25,'Betty');
so it returns all the names in the table plus 'JASON', or (25,'Betty').

You use it like this:
SELECT age, name
FROM users
UNION
SELECT 25 AS age, 'Betty' AS name
Use UNION ALL to allow duplicates: if there is a 25-years old Betty among your users, the second query will not select her again with mere UNION.

In SQL Server, you would say:
Select name from users
UNION [ALL]
SELECT 'JASON'
In Oracle, you would say
Select name from user
UNION [ALL]
Select 'JASON' from DUAL

is it possible to extend query results with literals like this?
Yes.
Select Name
From Customers
UNION ALL
Select 'Jason'
Use UNION to add Jason if it isn't already in the result set.
Use UNION ALL to add Jason whether or not he's already in the result set.

Related

SQLITE: Table names to select from as a subquery

I'm trying to select distinct values of one column from many tables at once. The two queries I want to combine are:
Select all the appropriate tables:
SELECT name
FROM sqlite_schema
WHERE type='table'
AND name NOT LIKE 'sqlite_%';
Select distinct values from one table:
SELECT DISTINCT CATEGORY FROM my_table;
I want to run this last query on each table name from the results of the first query. I'm pretty sure it should be possible, but haven't worked it out.
Something like this is what I imagine:
SELECT DISTINCT CATEGORY
FROM (
SELECT name
FROM sqlite_schema
WHERE type='table'
AND name NOT LIKE 'sqlite_%'
);
This combined query throws an error.
The best that you can do with SQLite is get the sql statement that you need as a string and execute it with the programming language of your choice:
SELECT GROUP_CONCAT('SELECT CATEGORY FROM ' || name, ' UNION ') AS sql
FROM sqlite_schema
WHERE type='table' AND name NOT LIKE 'sqlite_%';
You will get a string like:
SELECT CATEGORY FROM table1
UNION
SELECT CATEGORY FROM table2
UNION
SELECT CATEGORY FROM table3
I use UNION instead of SELECT DISTINCT.
See the demo.

Case statement to determine if I should union

I currently want to do some sort of conditional union. Given the following example:
SELECT age, name
FROM users
UNION
SELECT 25 AS age, 'Betty' AS name
Say I wanted to only union the second statement if the count of 'users' was >=2 , otherwise do not union the two.
In summary I want to append a table with a row if the table only has 2 or more values.
You could use an ugly hack something like this, but I think Tim's answer is better:
SELECT age, name
FROM users
UNION ALL
SELECT 25, 'Betty'
WHERE (SELECT COUNT(*) FROM users) > 1;
If it's in a stored-procedure you could use If...Else:
IF (SELECT COUNT(*) FROM users) < 2
BEGIN
SELECT age, name
FROM users
END
ELSE
SELECT age, name
FROM users
UNION ALL
SELECT 25 AS age, 'Betty' AS name
Otherwise you could try something like this:
SELECT age, name
FROM users
UNION ALL
SELECT TOP 1 25 AS age, 'Betty' AS name
FROM users
WHERE (SELECT COUNT(*) FROM users) >= 2
Note that i've used UNION ALL since it doesn't seem that you want to eliminate duplicates.
Played around here: http://sqlfiddle.com/#!6/a7540/2323/0
Edit: Instead of my second approach i prefer Zohar's. So if you can use If....Else prefer that otherwise WHERE (SELECT COUNT(*) FROM users) > 1 without a table.
Something like the following should work:
SELECT age, name
FROM users
UNION ALL
SELECT age, name
FROM (SELECT 25 AS age, 'Betty' AS name) x
CROSS APPLY (SELECT COUNT(*) FROM users) y(cnt)
WHERE y.cnt >= 2
Second part of UNION ALL will be NULL in case users table has less than 2 records.
SELECT age
, name
FROM users
UNION
SELECT 25 As age
, 'Betty' As name
WHERE EXISTS (
SELECT Count(*)
FROM users
HAVING Count(*) >= 2
)
;

How can I add a "custom" row to the top of a select result set?

I can select and pull out a list of records by using a select statement like so with t-sql:
select * from [dbo].[testTable];
But how can I add in a "custom" row to the top of the result set?
For example, if the result set was:
John john#email.com
Max max#domain.com
I want to add a row, which is not from the table, to the result set so that it looks like so:
Name Email
John john#email.com
Max max#domain.com
The reason why I want to do this is because I'm going to export this into a csv file through sqlcmd and I want to add in those "custom row" as headers.
This is the safe way to do this:
select name, email
from ((select 'name' as name, 'email' as email, 1 as which
) union all
(select name, email, 2 as which from [dbo].[testTable]
)
) t
order by which;
In practice, union all will work:
select 'name' as name, 'email' as email
union all
select name, email from [dbo].[testTable]
However, I cannot find documentation that guarantees that the first subquery is completed before the second. The underlying operator in SQL Server does have this behavior (or at least it did in SQL Server 2008 when I last investigated it).
SELECT name, email FROM (
SELECT 'Name' AS Name, 'Email' AS Email, 1 AS o
UNION ALL
SELECT name, email, 2 AS o FROM testTable
) t
ORDER BY o, name
The o column is added to order the result sets of the UNION so that you ensure the first result set appears on top.
SELECT * FROM
(SELECT 'Name' as name, 'Email' as email, 1 'rank'
union
SELECT name, email,3 'rank')a
ORDER BY a.rank,a.name
Try the above.

Add a string to SQL select

I am using SQL reporting service and working on paramters. One of paramters contains a list of cities. So, I have a dataset that
select city from MyCities
What I would like to do is to add a string for selecting all cities. So, I modifed the query to do something like
select city from Mycities union select 'ALL'
Only problem with this is that I want to show on the top of list so that it will be first itme on the list.
Is there a way I can sort the list so that it shows "All" first and followed by the name of actual cities?
Thanks.
Could you not do select 'ALL' union select city from Mycities
SELECT City
FROM
(
SELECT City, 1 AS Sorter FROM MyCities
UNION ALL
SELECT 'ALL' AS City, 0 AS Sorter
) iq
ORDER BY iq.Sorter ASC
I do this a lot and typically just wrap it with special characters, so that it stands out as well:
SELECT City
FROM (
SELECT City
FROM MyCities
UNION SELECT '<<ALL>>'
) X
ORDER BY City;
That will push it to the top of the list
Sure, it would be something like:
select 'ALL'
union
select city from Mycities
However you may receive a message about the amount of columns, so you may have to add blank '' to make it fit.
This would work to:
select 1 as id,'All' as city
union all
select 2,city from mycities
order by id,name
I think select 'ALL' union select city from Mycities actually works, but at any rate it isn't guaranteed, so you can do:
Select city
from (Select 'ALL' as city, 1 as myOrder
union
select city,2 as myOrder from Mycities)
order by myOrder

Get data origin after a UNION

I have a SQL query like this:
SELECT *
FROM (
(SELECT name FROM man)
UNION
(SELECT name FROM woman )
) AS my_table
ORDER BY name
how can I retrieve the source of my data?
For example if my result is like this:
Bob
Alice
Mario
...
I want to know if the name 'Bob' is retrieve from the 'man' table or from the 'woman' table.
SELECT *
FROM (
(SELECT name, 'man' as source FROM man)
UNION ALL
(SELECT name, 'woman' FROM woman )
) AS my_table
ORDER BY name
I added the UNION ALL becasue if these are mutually exclusive tables, it will be faster. If they are not, then adding the source will make the results mutually exclusive and you wil be able to see where the dups are. If they are not mutually exclusive but you only want to show one record, what business rule do you want to show which record you took?
A select can include a literal string, so the simplest way is probably to do:
SELECT *
FROM (
(SELECT name, 'man' as source FROM man)
UNION
(SELECT name, 'woman' as source FROM woman )
) AS my_table
ORDER BY name
These will only work if there is no intersection of Man & Woman.
If you expect duplicates, you will need to add some magic to the where clause.
and perhaps a 3rd query in the union to cover those where both exist.