Reputation: 4561
Given the following queries
Select Count(*) From TableA
Select Count(*) From TableB
Select Count(*) From TableC
Select Count(*) From TableD
I want to return a view like:
-----------
| Counts |
-----------
| 2 | --from TableA
-----------
| 3 | --from TableB
----------
| 4 | --from TableC
----------
| 5 | --from TableD
----------
I tried using UNION e.g:
CREATE VIEW [Foo]
AS
SELECT COUNT(*) AS [Counts]
FROM TableA
UNION
SELECT COUNT(*)
FROM TableB
UNION
SELECT COUNT(*)
FROM TableC
UNION
SELECT COUNT(*)
FROM TableD
But the order was incorrect
-----------
| Counts |
-----------
| 2 | --from TableA
-----------
| 3 | --from TableB
----------
| 5 | --from TableD
----------
| 4 | --from TableC
----------
Is there an alternative besides UNION I can use to produce the result set I want?
Upvotes: 0
Views: 231
Reputation: 1269633
Views return unordered result sets. You could try to do:
create view v_counts as
select . . .
order by . . .
And you'll get the error message:
The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified.
As the message suggests, there is a way to cheat to get around this, but I advise against it -- even when you cheat, the view is not guaranteed to return results in order.
Instead, include the table name:
Select 'TableA' as which, Count(*) From TableA
union all
Select 'TableB' as which, Count(*) From TableB
union all
Select 'TableC' as which, Count(*) From TableC
union all
Select 'TableD' as which, Count(*) From TableD;
Upvotes: 1
Reputation: 15175
Very close, just add a derived field for your order.
CREATE VIEW [Foo]
AS
SELECT TOP(100) PERCENT
*
FROM
(
SELECT COUNT(*) AS [Counts], RowOrder=1
FROM TableA
UNION
SELECT COUNT(*), 2
FROM TableB
UNION
SELECT COUNT(*), 3
FROM TableC
UNION
SELECT COUNT(*), 4
FROM TableD
)AS X
ORDER BY RowOrder
OR - Order outside of the count view.
CREATE VIEW [Foo]
AS
SELECT
*
FROM
(
SELECT COUNT(*) AS [Counts], RowOrder=1
FROM TableA
UNION
SELECT COUNT(*), 2
FROM TableB
UNION
SELECT COUNT(*), 3
FROM TableC
UNION
SELECT COUNT(*), 4
FROM TableD
)AS X
...
SELECT * FROM Foo ORDER BY RowOrder
Upvotes: 2
Reputation: 50163
UNION
internally does the sorting for you, you need union all
or define explicit ordring instead :
SELECT COUNT(*) AS [Counts]
FROM TableA UNION ALL
SELECT COUNT(*)
FROM TableB UNION ALL
SELECT COUNT(*)
FROM TableC UNION ALL
SELECT COUNT(*)
FROM TableD;
You can also define explicit ordering :
SELECT COUNT(*) AS [Counts], 1 as SortOrder
FROM TableA UNION
SELECT COUNT(*), 2
FROM TableB UNION
SELECT COUNT(*), 3
FROM TableC UNION
SELECT COUNT(*), 4
FROM TableD;
So, you need to use order by
clause in view Foo
select f.*
from Foo f
order by SortOrder;
Upvotes: 1