Oracle to Sql server: how to reproduce this select statement? - sql

I have a select statement that works in oracle. This is an imitation of how it looks like (the real statement is 200+ lines):
select * from (
select * from (
select id, name from my_table where name like 'D%' or name like 'Z%' order by name, id)
union all
select * from (
select id, name from my_table where name like 'K%' or name like 'T%' order by name, id)
union all
select * from (
select id, name from my_table where name like 'B%' or name like 'M%' order by name, id)
);
So, basially it's a union of 3 types of records from the same table. The outer "select * from" is automatically added and cannot be removed/changed. The ordering is important - records from the first subquery must be first, then records from the second one etc.
I need to rewrite it for sql server (preferably one common statement that works in oracle and sql server as well, but it's optional)
What I tried was:
select * from (
select * from (
select id, name, 1 as order_column from my_table where name like 'D%' or name like 'Z%') subquery
union all
select * from (
select id, name, 2 as order_column from my_table where name like 'K%' or name like 'T%') subquery
union all
select * from (
select id, name, 3 as order_column from my_table where name like 'B%' or name like 'M%') subquery
) outerquery order by order_column, name, id;
The ordering is preserved, but the order_column is included in result records and that is wrong.
So I changed it into:
select * from (
select id, name from (
select id, name, 1 as order_column from my_table where name like 'D%' or name like 'Z%') subquery
union all
select id, name from (
select id, name, 2 as order_column from my_table where name like 'K%' or name like 'T%') subquery
union all
select id, name from (
select id, name, 3 as order_column from my_table where name like 'B%' or name like 'M%') subquery
) parentquery order by order_column, name, id
But now, obviously the order_column is not visible in the outer query and it doesn't work. As I wrote before the "select * from" in first line cannot be changed - only the outer ORDER BY clause. Also the example conditions "name like 'D%'" are much more complex in reality and I cannot use them in some kind of outer order by ... case when ... (they must stay in subqueries)
I would be grateful for help.

Neither database guarantees the ordering of the result set without an order by.
Why not just do this in either database?
select id, name, 1 as order_column
from my_table
where name like 'D%' or name like 'Z%' or
name like 'K%' or name like 'T%' or
name like 'B%' or name like 'M%'
order by (case when name like 'D%' or name like 'Z%' then 1
when name like 'K%' or name like 'T%' then 2
when name like 'B%' or name like 'M%' then 3
end)
In SQL Server, you can simplify this to:
select id, name, 1 as order_column
from my_table
where name like '[DZKTBM]%'
order by (case when name like '[DZ]%' then 1
when name like '[KT]%' then 2
when name like '[BM]%' then 3
end)

Related

How to check result of a query using IF scripting in BigQuery?

I have a query and I want to check if the output has at least one row, if not , show some message like "No data". I have tried like described here : https://cloud.google.com/bigquery/docs/reference/standard-sql/scripting#if
WITH
cte1 AS (
SELECT id, name
FROM My_table
)
SELECT
* from cte1;
IF (SELECT COUNT(*) = 0 FROM cte1) THEN SELECT "No data"; END IF
You can do something like this:
WITH cte1 AS (
SELECT id, name
FROM My_table
)
SELECT id, name
FROM cte1;
UNION ALL
SELECT NULL, 'No Data'
FROM (SELECT 1 as x) x
WHERE NOT EXISTS (SELECT 1 FROM cte2);
Note: The subqueries need to return the same columns.

SQL query to display one record of each alphabet from a table

lets say there is one table called 'phone_book' have columns name and contact_no.
How to write a SQL query to display only first row from each alphabet from the column 'name' ?
You can use query like this,
Select Top 1 * from phone_book where name like 'A%'
UNION
Select Top 1 * from phone_book where name like 'B%'
UNION
Select Top 1 * from phone_book where name like 'c%'
UNION
Select Top 1 * from phone_book where name like 'D%'
.
.
.
.
.
Select Top 1 * from phone_book where name like 'Y%'
UNION
Select Top 1 * from phone_book where name like 'Z%'

Insert count from 2 diff tables

I want to insert in a table multiple counts I mean count all from cars and trucks and insert the result in a row in a table.
insert into table result(A,B)
select r1,r2 from(
select count(*) from trucks where fecha='X' and name like '%X%' and name not like '%X%' as r1,
select count(*) from cars where fecha='X' and name like '%X%' and name not like '%X%' as r2
)
;
I tried that but dont work... I do not know why...
I just discover I am using a hive enviroment and subqueries are not supported
Try enclosing your two subqueries with parentheses like this:
INSERT INTO table result(A, B)
VALUES (
(
SELECT COUNT(*)
FROM trucks
WHERE fecha='X' AND name LIKE '%X%' AND name NOT LIKE '%X%'
),
(
SELECT COUNT(*)
FROM cars
WHERE fecha='X' AND name LIKE '%X%' AND name NOT LIKE '%X%'
)
);
Try this like that :-
INSERT INTO destination_table (
Field_1,
Field_2
)
SELECT Field_1,
Field_2
FROM source_table;

How to use ORDER BY CHARINDEX() along with UNION?

How to use ORDER BY CHARINDEX() with UNION?
What I want is like:
select Id,Name from A where Name like '%Raspberry%'
Union
select Id,Name from B where Name like '%Raspberry%'
order by CHARINDEX('Raspberry',Name)
Common Table Expression will help you:
with cte as (
select Id,Name, CHARINDEX('Raspberry', Name) ci from #t1 where Name like '%Raspberry%'
Union
select Id,Name, CHARINDEX('Raspberry', Name) ci from #t2 where Name like '%Raspberry%'
)
select Id, Name
from cte
order by ci
SQL FIDDLE
AS you mentioned the problem is you have to select the column present in order by if you are using UNION. Try this.
select Id,Name,CHARINDEX('Raspberry',Name) as order_col
from A
where Name like '%Raspberry%'
Union
select Id,Name,CHARINDEX('Raspberry',Name) as order_col
from B
where Name like '%Raspberry%'
order by order_col

On SQL request by column

I have different simple SQL request that return only one value. Example
SELECT COUNT(*) FROM Person
OR
SELECT COUNT(*) FROM Category
I would to get all these infos in a unique request, with a column by request...
I tried something like that but it doesn't work :
SELECT COUNT(C.CategoryId) As nbPeople, COUNT(P.PersonID) As nbCategories FROM Category C, Person P
This works but I get only one column, and a row by request
SELECT COUNT(*) FROM Person UNION SELECT COUNT(*) FROM Category
How Can I simply do that ?
Thanks
When using SQL Server, you can try this:
SELECT ( select COUNT(C.CategoryId)
from Category C
) As nbPeople
, ( select COUNT(P.PersonID)
from Person P
) As nbCategories
In Oracle for example, you need to add this at the bottom
FROM dual
You can use UNION ALL like following:
SELECT '' AS [StatisticName], 1 AS [StatisticCount]
WHERE 1=0
UNION ALL
SELECT 'PersonCount', COUNT(*) FROM [Person]
UNION ALL
SELECT 'CathegoryCount', COUNT(*) FROM [Category]
First select with WHERE 1=0 is for create column header names only and is not necessary.
Try this.
select * from
(select count(*) cnt1
from Table1) t1
join
(select count(*) as cnt2
from Table2) t2 on 1=1