In SQL Server 2008, we can use Union/Unino All to put two results together, but I want to add order by for the final result. How can do that?
What I want is something like:
select id1 as id, * from ...
Union All
select id2 as id, * from ...
order by id
Help please. Thanks.
As noted in the comments, the pseudocode you've given should work, applying the order by to the combined result set. If you're trying to order in such a way that the two result sets are kept distinct, you'd need to introduce an artificial sort column, such as:
select id1 as id, *, 1 as MySortKey from ...
Union All
select id2 as id, *, 2 as MySortKey from ...
order by MySortKey, id
You can use this query as well
select * from (
select id1 as id, * from ...
Union All
select id2 as id, * from ...
) aaaa
order by id
use this code:
Select * from
(select id1 as id, * from ...
Union All
select id2 ad id, * from ...
order by id) as t
order by t.id
use northwind
select OrderID, ProductID from [Order Details] a
UNION all
Select OrderID, EmployeeID from Orders b
order by a.ProductID
All of these answers included the original poster's attempt is just plain confusing or overly complicated. A simple and easy to follow explanation is here:
How to order by with union
with,
"Just write
Select id,name,age
From Student
Where age < 15
Union
Select id,name,age
From Student
Where Name like "%a%"
Order by name
the order by is applied to the complete resultset
"
Just use UNION ALL instead of UNION here.
Related
I have a dataset that looks like this
StudentName Course Studentmailid Score
Student1 A student1#gmail.com. 80
Student1 A student1#gmail.com. 75
Student2 A student2#gmail.com. 70
Student1 B student2#gmail.com. 70
Now I want records 1,3,4.Basically the first occurance of the student in each Course
I have my query as
select distinct StudentName,Course, Studentmailid,Score fromStudentTable group by Course
and it throws an error.What would I have to tweak the query as to get the desired output
Hope it help.
;with cte as (
select StudentName,Course, Studentmailid,Score, Row_Number() over (partition by StudentName, Course order by StudentName) as Row_Num from StudentTable
)
select * from cte where Row_Num = 1
You need a column to define first item from multiple rows. Other wise there is no guaranty that you will get the same output every time. Following is a sample where I order by NULL, which will return record on normal order. But this will not always return the same result.
You need a column with values to order all records. You can then simply replace the ordering part in WINDOW function with your column.
Demo Here
SELECT * FROM
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY StudentName, Course ORDER BY (SELECT NULL)) RN
-- ORDER BY (SELECT NULL) is basically to keep data as it is now in the table
-- But there is no guaranty that it will order data in same order always
FROM your_table
)A
WHERE RN=1
I have a query which produces several results. I have concatenated several columns into 1 as an ID. I only want to show the rows where the ID is unique.
The below image is an example of my table:
As you can see the ID is repeated a few times. How can I construct a query to show only the 3 unique rows?
Nesting this query and using distinct(RowID) shows the three rows but I cannot show the rest of the columns?
Any ideas welcome. Thank you!
Use distinct in the select for all columns
Query:
select distinct RowID, OrderNum, cDescription, Thickness, UllTimberThickness, Width, UllTimberWidth, Length
from YourTable
Use GROUP BY:
SELECT RowID, OrderNum, cDescription, Thickness, etcetera ...
FROM dbo.TableName
GROUP BY RowID, OrderNum, cDescription, Thickness, etcetera ...
( etcetera is a placeholder for the rest of your columns )
Try this:
SELECT *
FROM mytable t1
WHERE
(SELECT COUNT(*) FROM mytable t2
where t2.id = t1.id) = 1
In this way, you get all rows where id is unique. I write this query because I don't know if at your ID other fields are the same, because you have built your field with a set of information. If all the columns are the same for equal id so you can use the statement DISTINCT as adviced you by Vasanth Sundaralingam in his post.
I'm a little confused by what "get the three unique rows means".
If you mean rows that are unique, use count(*) as a window function:
select *
from (select t.*,
count(*) over (partition by id) as cnt
from t
) t
where cnt = 1;
If you mean one example of each row, use row_number():
select *
from (select t.*,
row_number(*) over (partition by id order by (select NULL)) as seqnum
from t
) t
where seqnum = 1;
I was trying to select the second last row with SQL Server. So I wrote a query like this:
SELECT TOP 1 * From Cinema
WHERE CinemaID!=(SELECT TOP 1 CinemaID
FROM Cinema
ORDER BY CinemaID DESC)
ORDER BY CinemaID DESC
and it did what I need. But I want to do the same thing with only one select.
I read that the LIMIT clause in MySql does that. But I couldn't find any equivalent
of that. So I appreciate any help about finding something useful.
To get the 2nd last row in one select:
SELECT TOP 1 * From
(select Top 2 * from Cinema ORDER BY CinemaID DESC) x
ORDER BY CinemaID
It's really only "one" select because the outer select is over only 2 rows.
The best way to do this (and compatible with the ANSI SQL standard), is to use a CTE (Common Table Expression) with the ROW_NUMBER function:
;WITH OrderedCinemas AS
(
SELECT
CinemaID, CinemaName,
ROW_NUMBER() OVER(ORDER BY CinemaID DESC) AS 'RowNum'
FROM dbo.Cinema
)
SELECT
CinemaID, CinemaName
FROM OrderedCinemas
WHERE RowNum = 2
By using this construction, you can get the second highest value very easily - or the fifth hightest (WHERE RowNum = 5) or the top 3 rows (WHERE RowNum <= 3) or whatever you need - the CinemaID values are just ordered and sequentially numbered for your use.
The following doesn't work, explaination of why:
Using ranking-function derived column in where clause (SQL Server 2008)
I'll keep it here for completeness:
SELECT row_number() OVER (ORDER BY col) r, *
FROM tbl
WHERE r = 2
More info:
http://www.bidn.com/blogs/marcoadf/bidn-blog/379/ranking-functions-row_number-vs-rank-vs-dense_rank-vs-ntile
So I think the most readable way of doing it is:
SELECT * FROM (SELECT row_number() OVER (ORDER BY col) r, * FROM tbl) q
WHERE r = 2
Since this (old) question has not been tagged with a specific SQL-Server version and none of (the very good) answers uses only one SELECT clause - for the good reason that it was not possible in old verions - here is one that works only in recent, 2012+ versions:
SELECT c.*
FROM dbo.Cinema AS c
ORDER BY CinemaID DESC
OFFSET 1 ROW
FETCH FIRST 1 ROW ONLY ;
Tested at SQLFiddle
SELECT TOP 1 * FROM tbl_CompanyMaster
where Companyid >= (SELECT MAX(Companyid) - 1 FROM tbl_CompanyMaster)
select * from TABLE_NAME order by COLUMN_NAME desc limit 1,1 ;
Where COLUMN_NAME should be "primary key" or "Unique"
Two selects but a bit quicker
select top 1 * from(
SELECT TOP 2 * From Cinema
WHERE CinemaID
ORDER BY CinemaID DESC) top2
Order by CinemaID
So, in the spirit of only using one SELECT clause as stated in the OP and thoroughly abusing T-SQL in general, I proffer something I would never, ever recommend using in production that nevertheless satisfies the stated criteria:
update Cinema
set Cinema.SomeField = Cinema.SomeField
output inserted.*
from Cinema
inner join
(
select top 2 CinemaID, ROW_NUMBER() over (order by CinemaID desc) as RowNum
from Cinema
) rsRowNum on rsRowNum.CinemaID = Cinema.CinemaID
where RowNum = 2
This query will also work for SQLITE
SELECT * From
(select * from Cinema ORDER BY CinemaID DESC LIMIT 2) AS name
ORDER BY CinemaID LIMIT 1
You're only using one SELECT statement. A SELECT statement can include an arbitrary (more or less) number of subqueries--correlated subqueries, scalar subqueries, and so on, each with their own SELECT clause. But it's still just one SELECT statement.
If you want to avoid a subquery, you could select the top 2, and skip the one you don't want. That kind of programming is pretty brittle, though. You have to remember what to skip every time; sooner or later, you'll forget.
SELECT field_name FROM (SELECT TOP 2 field_name FROM table_name
ORDER BY field_name DESC)
WHERE rownum = 2;
select top 1* from(SELECT TOP 2 * From Cinema
WHERE CinemaID
ORDER BY CinemaID DESC) XYZ
ORDER BY CinemaID
where XYZ is not a keyword. It is just a word. And word can be anything.
If you need to do that, but:
the column is different than id
you need to order by some specific column
can't use SELECT on FROM clause (if you are using old versions of Hibernate, per example).
You can do:
select top 1 * from Cinema
where date < (select MAX(date) from Cinema)
order by date desc
The easiest way to get second last row from sql table is user ORDER BY CinemaID DESC and set LIMIT 1,1
TRY THIS
SELECT * from `Cinema` ORDER BY `CinemaID` DESC LIMIT 1,1
select * from
(select ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) as R, * from Cinema ) T1
where (select count(*) from Cinema ) - T1.R = 1
SELECT * FROM record
WHERE record_id=(SELECT max(record_id)-1 FROM record)
Here is my code:
SELECT * From
(select * from table name ORDER BY column name DESC LIMIT 2) AS xyz
ORDER BY column name LIMIT 1;
I have a table like so:
Id, Comment, LastUpdatedDate
I'm tyring to select the latest comment for that id. The table can have many comments on that id with different dates but I'm trying to get the latest date out of there. I've tried the following with no success:
SELECT tt.*
FROM tagtestresultcomment tt
INNER JOIN
(
SELECT tag_id, MAX(last_update) AS MaxDateTime
FROM tagtestresultcomment
GROUP BY tag_id
) groupedtt ON tt.tag_id = groupedtt.tag_id AND tt.last_update = groupedtt.MaxDateTime
order by tag_id
Does anyone have any ideas of how to achieve this?
Thanks!
It sounds like you want only the latest comment for each tag_id? In which case, here is one approach you can use from SQL 2005 and on:
;WITH CTE AS
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY tag_id ORDER BY last_update DESC) AS RowNo
FROM TagTestResultComment
)
SELECT * FROM CTE WHERE RowNo = 1
try this
Select * from tagtestresultcomment where last_update in
(select max(last_update) from tagtestresultcomment group by tag_id)
your query code is too redundant. first
tt.tag_id = groupedtt.tag_id AND tt.last_update = groupedtt.MaxDateTime
it's enough just
tt.tag_id = groupedtt.tag_id
and second, it's enough just
SELECT [desired field list extcept last_update and ],
tag_id,
MAX(last_update) AS MaxDateTime
FROM
tagtestresultcomment
group by
tag_id, [desired field list extcept last_update and tag_id]
at all to achieve your objective
I have tried something like this:
declare #tagtestresultcomment table
(
id int
, comment varchar(50)
,LastUpdatedDate datetime
)
--==== Populate table
insert into #tagtestresultcomment(id,comment,LastUpdatedDate)
select 1,'My name is Arthur','2011-06-09 00:00:00' union all
select 2,'My name is DW','2011-06-19 00:00:00' union all
select 2,'Arthur is my brother','2011-06-21 00:00:00' union all
select 1,'I have a sister named DW','2011-06-21 00:00:00' union all
select 3,'I am Muffy','2011-06-14 00:00:00' union all
select 3,'I like sports','2011-06-14 00:00:00'
-- SELECT stmt
select * from #tagtestresultcomment t
join
(
select id, MAX(lastupdateddate) as LastUpdatedDate from #tagtestresultcomment group by id
) m
on t.id = m.id
and t.LastUpdatedDate = m.LastUpdatedDate
The "MAX" group function wasn't working for me, so I used a sub-query. I had trouble wrapping my head around your single table example, so I'm using a common parent-child 1-to-many relationship with a blog and comment tables as an example.
SELECT
b.id,
b.content,
c.id,
c.blog_id,
c.content,
c.last_update
FROM blog b
INNER JOIN blog_comment c
ON b.id = c.blog_id AND c.id = (
SELECT TOP 1 id FROM blog_comment WHERE blog_id = b.id ORDER BY last_update DESC
)
The query takes a hit on my sub-query, as it will call that "SELECT TOP 1" query for each record in the blog table. I'd like to hear of a faster, more efficient example if possible.
I would like to create a select query statement with autonumber.. like..
select * from tbl1
will give me everything from table.
The result I'd like to get is..
1 data
2 data
3 data
So how can I do to get that number..??
like..
select (for autonumber), * from tbl1
the data in my table will repeated (no unique data)
Use ROW_NUMBER:
SELECT ROW_NUMBER() OVER (ORDER BY col1) AS rn, * FROM tbl1
To filter the results based on the row number use this:
SELECT * FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY col1) AS rn, * FROM tbl1
) T1
WHERE rn = 5
You may need to find the identity's offset e.g. last ID of second table:
DECLARE #lastAutoID int
SET #lastAutoID = abs(( Select max(convert(float,[ConsID]))
FROM [RXPIPEDB]...[consumption] ) )
Then use ROW_NUMBER():
#lastAutoID + ROW_NUMBER() OVER (ORDER BY oldICN_str)