SQL order by in union all query - sql

I have following query which produces following below data.
All I want to show list of users in Alphabetically order and First Record should be All , All.
Query:
SELECT 'All' created_by,
'All' Prepby
FROM dual
UNION ALL
SELECT DISTINCT
to_char(d.created_by) AS created_by,
get_user_name(d.created_by) Prepby
FROM Hpml_Gp_dtl d
WHERE d.created_by IS NOT NULL
ORDER BY 2;

Use a CASE expression in ORDER BY.
Query
select t.* from (
select 'All' created_by, 'All' Prepby
from dual
union all
select distinct to_char(d.created_by) as created_by,
get_user_name(d.created_by) Prepby
from Hpml_Gp_dtl d
where d.created_by is not null
) t
order by case Prepby when 'All' then 1 else 2 end, Prepby;

Perform the ORDER BY in a sub-query:
SELECT 'All' AS created_by,
'All' AS Prepby
FROM DUAL
UNION ALL
SELECT *
FROM (
SELECT DISTINCT
to_char(created_by),
get_user_name(created_by)
FROM Hpml_Gp_dtl
WHERE created_by IS NOT null
ORDER BY 2
)

Related

update statement is not working in my query

with t as (
select 'AA-00001152' itemid from dual union all
select 'AA-00001152' from dual union all
select 'AA-00001153' from dual union all
select 'AA-00001154' from dual union all
select 'AA-00001154' from dual union all
select 'CC-254565' from dual union all
select 'AA-00001156' from dual union all
select 'AA-00001156' from dual union all
select 'BB-00001200' from dual
)
select 14999 + dense_rank() over(order by itemid) as seq_no,
itemid
from t
order by seq_no
Here i have generated seq_no for multiple itemIds, but i am trying to update in a seq_no column which is throwing error saying subquery returns more than one row. Please help in update query. thanks.
my update query:-
update test
set seq_num =14999 + dense_rank() over(order by itemid)
where item_type='non_product')
In SQL Server, you can use an updatable CTE:
with toupdate as (
select dense_rank() over (order by itemid) as seqnum,
t.*
from t
)
update toupdate
set seq_num = 14999 + seqnum
where item_type = 'non_product';
However, I suspect that you are not really using SQL Server. This syntax would not work in most other databases.

Is there an alternative to union all that can stack data on top of each other?

I need to create a view that stacks various possible cuts of data on top of each other. In my example, I have the fields id, location, and sub_location. I need every possible combination of the data as shown below. So far, I've been doing this using union all, but in reality I have about 15 different fields that I need to cut by and using union all for this is causing what is a relatively basic query to become very large and error-prone.
select a.id, a.location, a.sub_location
from a
union all
select 'All' id, a.location, a.sub_location
from a
union all
select 'All' id, 'All' location, a.sub_location
from a
union all
select 'All' id, 'All' location, 'All' sub_location
from a
union all
select 'All' id, a.location, 'All' sub_location
from a
union all
select a.id, 'All' location, 'All' sub_location
from a
union all
select a.id, 'All' location, a.sub_location
from a
union all
select a.id, a.location, 'All' sub_location
from a;
Any suggestions for a cleaner way to do this?
Hmmm. You could do what you are doing using cross join:
select coalesce(tid.id, a.id) as id,
coalesce(tloc.location, a.location) as location,
coalesce(tloc.sub_location, a.sub_location) as sub_location
from a cross join
(select 'ALL' as id union all NULL end) tid cross join
(select 'ALL' as location union all NULL end) tloc cross join
(select 'ALL' as sub_location union all NULL end) tsubloc ;

Why do I still get duplicates on [CONMAT_MATCHING_DONOR] even after using DISTINCT?

I still get duplicates on [CONMAT_MATCHING_DONOR] even after using DISTINCT.
SELECT TOP 1000 [CONTRIB_MATCH_ID]
,[CONMAT_CONTRIBUTION]
,[CONMAT_FORM_RECEIVED_DATE]
,[CONMAT_MATCHING_DONOR]
,[CONMAT_STATUS]
,[STATUS_DESC]
,[CONMAT_STATUS_DATE]
FROM [ods_production].[dbo].[SPT_CONTRIB_MATCH]
WHERE [CONMAT_MATCHING_DONOR] IN (SELECT DISTINCT
[CONMAT_MATCHING_DONOR]
FROM [ods_production].[dbo].[SPT_CONTRIB_MATCH])
ORDER BY [CONMAT_MATCHING_DONOR] DESC
Your usage of DISTINCT in the IN clause doesn't make much sense - this will not affect the results of your query in any way.
Consider:
WITH v_base(name) AS (
SELECT 'A' UNION ALL
SELECT 'A' UNION ALL
SELECT 'B')
SELECT name FROM v_base WHERE name IN (SELECT DISTINCT name from v_base)
which more or less translates to
WITH v_base(name) AS (
SELECT 'A' UNION ALL
SELECT 'A' UNION ALL
SELECT 'B')
SELECT name FROM v_base WHERE name IN ('A', 'B')
vs
WITH v_base(name) AS (
SELECT 'A' UNION ALL
SELECT 'A' UNION ALL
SELECT 'B')
SELECT DISTINCT name FROM v_base WHERE name IN (SELECT name from v_base)
which translates to
WITH v_base(name) AS (
SELECT 'A' UNION ALL
SELECT 'A' UNION ALL
SELECT 'B')
SELECT DISTINCT name FROM v_base WHERE name IN ('A', 'A', 'B')
and the difference should become clear.
SQL Fiddle

How to do a case sensitive GROUP BY?

If I execute the code below:
with temp as
(
select 'Test' as name
UNION ALL
select 'TEST'
UNION ALL
select 'test'
UNION ALL
select 'tester'
UNION ALL
select 'tester'
)
SELECT name, COUNT(name)
FROM temp
group by name
It returns the results:
TEST 3
tester 2
Is there a way to have the group by be case sensitive so that the results would be:
Test 1
TEST 1
test 1
tester 2
You need to cast the text as binary (or use a case-sensitive collation).
With temp as
(
select 'Test' as name
UNION ALL
select 'TEST'
UNION ALL
select 'test'
UNION ALL
select 'tester'
UNION ALL
select 'tester'
)
Select Name, COUNT(name)
From temp
Group By Name, Cast(name As varbinary(100))
Using a collation:
Select Name Collate SQL_Latin1_General_CP1_CS_AS, COUNT(name)
From temp
Group By Name Collate SQL_Latin1_General_CP1_CS_AS
You can use an case sensitive collation:
with temp as
(
select 'Test' COLLATE Latin1_General_CS_AS as name
UNION ALL
select 'TEST'
UNION ALL
select 'test'
UNION ALL
select 'tester'
UNION ALL
select 'tester'
)
SELECT name, COUNT(name)
FROM temp
group by name
Simply:
SELECT count(*), CAST(lastname as BINARY) AS lastname_cs
FROM names
GROUP BY lastname_cs;
In MySQL/MariaDB, if you don't want to use collations or casting to binary, just use:
SELECT MAX(name), COUNT(name)
FROM (
select 'Test' as name
UNION ALL
select 'TEST'
UNION ALL
select 'test'
UNION ALL
select 'test'
UNION ALL
select 'tester'
UNION ALL
select 'tester'
) as tmp
group by MD5(name)
This works on my case:
SELECT BINARY example FROM table GROUP BY BINARY example;

ORDER BY CASE does not working?

Hi I have SQL statement in DB2 which is working.
select distinct 'IN' as STATUS,
(select count(*) from table.......)
from table
UNION ALL
select distinct 'OUT',
(select count(*) from table.......)
from table
UNION ALL
select distinct 'FINISHED',
(select count(*) from table.......)
from table
order by status
But if I change the last line to
order by
case STATUS
when 'IN' then 1
when 'OUT' then 2
when 'FINISHED' then 3
end
My query does not work.
Can someone tell me how to solve this?
Thanks
Try wrapping the UNION into a derived table and order on that:
select *
from (
.... here goes your statement ...
) t
order by
case STATUS
when 'IN' then 1
when 'OUT' then 2
when 'FINISHED' then 3
end
you could always add the sort # to the status:
select distinct '1-IN' as STATUS,
(select count(*) from table.......)
from table
UNION ALL
select distinct '2-OUT',
(select count(*) from table.......)
from table
UNION ALL
select distinct '3-FINISHED',
(select count(*) from table.......)
from table
order by status
hello try this should work if i remember correctly
order by
case
when STATUS='IN' then 1
when STATUS='OUT' then 2
when STATUS='FINISHED' then 3
end
you could also name this when finishing
end as field_name