SQL Query, Union Order by like a tree - sql

Hello I have a query like
SELECT 4 AS sortf,XX FROM Table GROUP BY Y
UNION
SELECT 1 AS sortf,XX FROM Table GROUP BY Y
UNION
SELECT 2 AS sortf,XX FROM Table GROUP BY Y
UNION
SELECT 3 AS sortf,XX FROM Table GROUP BY Y
ORDER BY 3,2
My problem is that the line 2 and 3 ar not ordered like a tree. I tried some other combinations but it did not work.

if you want to sort your dataset according to numbers put your code and unions into a common table expression and the use ROW_NUMBER() function to generates row number , something like this :
WITH CTE
AS
(
SELECT 4 AS sortf, productid FROM Production.Products
UNION
SELECT 1 AS sortf,productid FROM Production.Products
UNION
SELECT 2 AS sortf,productid FROM Production.Products
UNION
SELECT 3 AS sortf,productid FROM Production.Products
)
SELECT *, ROW_NUMBER() OVER (ORDER BY productid) AS SortOrder
FROM CTE
ORDER BY SortOrder

Related

How to SUM via Group By?

I have a table something like this:
ID Marks Weightatthistime
1 5 44
1 5 43
1 5 41
2 4 39
2 4 38
I want the total marks obtained by the IDs, so I want my query to return: 9.
I know I could do a:
select ID, sum(Marks) from table group by 1
but I simply just want the total sum and not another mini table. The table is aggregated at this level and there's no way for me to change it.
Use subquery :
select id, sum(marks)
from (select distinct id, marks
from table t
) t
group by id;
If you want only sum then use only sum(marks) :
select sum(marks)
from (select distinct id, marks
from table t
) t;
use distinct
select sum( distinct Marks) from table
with cte as
(
select 1 id, 5 as m union all
select 1,5 union all
select 1,5 union all
select 2,4 union all
select 2,4
) select sum(distinct m) from cte
but if multiple user have same number then follow subquery method that #Yogesh shown
output
9
I believe this should work with any ANSI SQL engine.
Select ID, Marks, Weightatthistime, (Select Sum(Marks) From Table1) SumAllMarks
From Table1
This will put 9 on each record.
SELECT sum(DISTINCT marks) FROM table;
You can use this query to get the sum of the distinct mark values.

explode tables in sql

Problem statement:
I have Product_id and Quantity column in my table
Say product_id A has 2 units, B has 3 units etc
How do i make a table with 2 rows of Product_id A, 3 rows of Product_id B?
I did this exercise based on a recursive Common Table Expression:
;WITH CTE (Vals)
AS (
SELECT 1
UNION ALL
SELECT 1 + Vals
FROM CTE WHERE Vals< 99
)
SELECT Product_id
FROM Mytable A
INNER JOIN CTE C ON C.Vals <= A.Quantity
ORDER BY A.Product_id
supposing Quantity < 99
could help you
This worked for me, tested on your example :
WITH tally(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM tally WHERE n<100)
SELECT Product_id, 1 as Quantity
FROM MyTable CROSS JOIN tally
WHERE n<=quantity
ORDER BY Product_id;

multiple select in one query [Teradata]

I'm trying to do multiple select from diff tables and just have a result in one column.
SELECT COUNT(*) FROM tb1 union
SELECT COUNT(*) FROM tb2 union
SELECT COUNT(*) FROM tb3;
output should be like:
593643
18103600
0
Problem with this is that the result is being arranged on desc order.
Like below:
0
593643
18103600
I would want the result to be as I put the select statement.
Please advise. Btw, I'm using teradata.
Thank you.
SQL result sets are inherently unordered, unless you explicitly specify an order by clause. You can do this with a subquery:
select cnt
from ((SELECT COUNT(*) as cnt, 1 as ord FROM tb1)
union all
(SELECT COUNT(*), 2 FROM tb2)
union all
(SELECT COUNT(*), 3 FROM tb3)
) t
order by ord
If you want specific order, add ORDER BY clause. It would also be good to use UNION ALL so you always get 3 rows, even with duplicate results (two tables having the same number of rows):
SELECT 'tbl1' AS tablename, COUNT(*) AS cnt, 1 AS ord FROM tb1 UNION ALL
SELECT 'tbl2', COUNT(*), 2 FROM tb2 UNION ALL
SELECT 'tbl3', COUNT(*), 3 FROM tb3
ORDER BY ord ;

'SELECT IN' with item list containing duplicates

I'm doing
SELECT Name WHERE Id IN (3,4,5,3,7,8,9)
where in this case the '3' Id is duplicated.
The query automatically excludes the duplicated items while for me would be important to get them all.
Is there a way to do that directly in SQL?
The query doesn't exclude duplicates, there just isn't any duplicates to exclude. There is only one record with id 3 in the table, and that is included because there is a 3 in the in () set, but it's not included twice because the 3 exists twice in the set.
To get duplicates you would have to create a table result that has duplicates, and join the table against that. For example:
select t.Name
from someTable t
inner join (
select id = 3 union all
select 4 union all
select 5 union all
select 3 union all
select 7 union all
select 8 union all
select 9
) x on x.id = t.id
Try this:
SELECT Name FROM Tbl
JOIN
(
SELECT 3 Id UNION ALL
SELECT 4 Id UNION ALL
SELECT 5 Id UNION ALL
SELECT 3 Id UNION ALL
SELECT 7 Id UNION ALL
SELECT 8 Id UNION ALL
SELECT 9 Id
) Tmp
ON tbl.Id = Tmp.Id

Union Select Only One Row

I Have a query with Two Select Clause combines with UNION.I want to select only top first row. How can i do that Using Union ?
Select Fault,OccurredOn From ATMStatus Where Ticket=189703 // This Will retrieve single record as the primary key is applied
Union
Select Fault,OccurredOn From ATMStatusHistory Where Resolved=0 AND Ticket=189703 Order By OccurredOn Desc
select top 1 * from
(
Select Fault,OccurredOn
From ATMStatus
Where Ticket=189703
Union
Select Fault,OccurredOn
From ATMStatusHistory
Where Resolved=0 AND Ticket=189703
) x
Order By OccurredOn Desc
This returns 2 rows:
select 1 as id
union
select 2 as id
This returns 1 row:
select top 1 * from (
select 1 as id
union
select 2 as id
) as x
order by id