Ambiguous Error while column name is used in order by clause - sql

I have encountered one issue below
SELECT ColumnName1,*
FROM TableName
WHERE ColumnName = 'XXXXXX'
ORDER BY ColumnName1
From above query it throws error as Ambiguous column name Column Name1.
Even though I have not used number tables then too it throws error like this. Can anybody tell what the reason behind this.

Because the SELECT has two columns called ColumnName1 -- one placed there explicitly and one from the *. Here are some choices:
SELECT t.ColumnName1, t.*
FROM TableName t
WHERE t.ColumnName = 'XXXXXX'
ORDER BY t.ColumnName1
or:
SELECT t.ColumnName1, t.*
FROM TableName t
WHERE t.ColumnName = 'XXXXXX'
ORDER BY 1
or:
SELECT t.ColumnName1 as second_columnname1, t.*
FROM TableName t
WHERE t.ColumnName = 'XXXXXX'
ORDER BY second_columnname1

To resolve an error we have 3 options:
-- 1. give alias to the column
SELECT A AS A_STANDS_ALONE, *
FROM YourTable
ORDER BY A
-- 2. order by 1
SELECT A, *
FROM YourTable
ORDER BY 1
-- 3. give alias to the table and used it in column call and order by
SELECT t.A, *
FROM YourTable t
ORDER BY t.A

Related

How to change a UNION to a IN clause?

I need to get a maximum of 3 distinct records from the same table, so currently I'm doing:
SELECT 1, mycolumn FROM mytable WHERE id = #firstId
UNION ALL
SELECT 2, mycolumn FROM mytable WHERE id = #secondId
UNION ALL
SELECT 3, mycolumn FROM mytable WHERE id = #thirdId
The actual SELECT part contains over 20 columns and the FROM part contains a number of JOINs. The first column is a constant and is always fixed depending on the record. I don't know how many records might return. It could be anything from 0 to 3 records.
Is it possible to change the above query so that it uses IN like this:
SELECT ???, mycolumn FROM mytable WHERE id IN (#firstId, #secondId, #thirdId)
But how do I explicitly map each record to the fixed constant if I use IN?
You may use a CASE expression here with a single query:
SELECT
CASE id WHEN #firstId THEN 1
WHEN #secondId THEN 2
WHEN #thirdId THEN 3 END AS val,
mycolumn
FROM mytable
WHERE
id IN (#firstId, #secondId, #thirdId);
If you wish to also order by the computed column, then add ORDER BY val to the end of the above query.
You can use CASE like following.
SELECT
CASE
WHEN id= #firstId THEN 1
WHEN id=#secondId THEN 2
ELSE 3
END AS rn,
mycolumn
FROM mytable
WHERE id IN (#firstId,
#secondId,
#thirdId)
Another approach can be using DENSE_RANK if you have one record for each provided id and #firstId, #secondId & #thirdId are in ascending order.
SELECT DENSE_RANK()
OVER(
ORDER BY id) rn,
mycolumn
FROM mytable
WHERE id IN ( #firstId, #secondId, #thirdId )
I would recommend a table-valued constructor for this purpose:
select v.outputnum, my_column
from mytable t join
(values (#firstid, 1),
(#secondid, 2),
(#thirdid, 3)
) v(id, outputnum)
on t.id = v.id
order by v.outputnum;
I think this is simpler than other versions, because the list of ids is only present once in the query -- so no danger of different parts of the query getting out of sync.

SQL Server Database Error: Only one expression can be specified in the select list when the subquery is not introduced with EXISTS

Can any one please help me regarding that error in SQL server
" SQL Server Database Error: Only one expression can be specified in the select list when the subquery is not introduced with EXISTS."
select * from
(select row_number() over ( order by (select null) ) rn,
(select distinct test1,test2,test3
from table1
where table1.test1= 1
EXCEPT
select distinct test1,test2,test3
from table2
where table2.test1= 1)
)
where rn between 0 and 100
Try this:
select * from
(select row_number() over ( order by (select null) ) rn,a.test1,a.test2,a.test3
from (select distinct test1,test2,test3
from table1
where table1.test1= 1
EXCEPT
select distinct test1,test2,test3
from table2
where table2.test1= 1) a
) b
where b.rn between 0 and 100
There are multi errors in your query:-
First one:-
Incorrect syntax near the keyword 'where'
Fix: Type alias for derived table (I am gonna type myTable as an alias below)
second one:-
No column name was specified for column 2 of 'myTable'
Fix: Type alias for derived column (I am gonna type myCol as an alias below)
Third one:- (Thant you mentioned in your question)
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
Reason: You can't return two (or multiple) columns in your subquery.
The resolved Query:-
select * from
(
select
row_number() over ( order by (select null) ) rn,
(
select distinct test1
from table1
where table1.test1= 1
EXCEPT
select distinct test1
from table2
where table2.test1= 1
) myCol
) myTable
where rn between 0 and 100
Maybe the result is not what you need, but unless this a working query and now you have the keys for handling yours as your needs.

How to get duplicate text values from SQL query

I have to get table only with duplicate text values using SQL query. I have used Having count(columnname) > 1 but I'm not getting result, only with duplicate values instead getting all values.
Can anyone suggest whether I have to add anything to my query?
Thanks.
Use the below query. mention the column which is getting duplicated in the patition by clause..
with CTE_1
AS
(SELECT *,COUNT(1) OVER(PARTITION BY LTRIM(RTRIM(REPLACE(yourDuplicateColumn,' ',''))) Order by -anycolunm- ) cnt
FROM YourTable
)
SELECT *
FROM CTE_1
WHERE cnt>1
Assuming id is a primary key
select *
from myTable t1
where exists (select 1
from myTable t2
where t2.text = t1.text and t2.id != t1.id)
You can use similar to following query:
SELECT
column1, COUNT(*)
FROM table
GROUP BY column1
HAVING COUNT(*) > 1

How to Order BY without having Column in SELECT

I am using MS-SQL and I have a table like this:
Count Code
1 A
2 C
3 A
4 B
5 C
6 B
I need to only to get Distinct Row of the Code Column but I need to keep the Order of the Column to create a Comma Delimited String like this:
A, C, B
I have tried the following code to not get an SQL Error of Msg 145, Level 15 - ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
SELECT #tlist = ISNULL(#tlist+', ','') + Code
FROM (SELECT DISTINCT t.Code
FROM #Table t)
but I get an output of A, B, C
So, you don't want distinct. You want group by:
select t.code
from #Table t
group by t.code
order by min(count)
You can order by columns not mentioned in the select clause.
To get the comma delimited list as a single variable, use this technique:
select stuff((select ', '+t.code
from #Table t
group by t.code
order by min(count)
for xml path ('')
), 1, 2, '')
Order by in a subquery is generally undefined. And, your method of concatenating the list together in order is not guaranteed to work.
order them in your subquery
SELECT DISTINCT t.Code
FROM #Table t
ORDER BY t.Code

Select top and bottom rows

I'm using SQL Server 2005 and I'm trying to achieve something like this:
I want to get the first x rows and the last x rows in the same select statement.
SELECT TOP(5) BOTTOM(5)
Of course BOTTOM does not exist, so I need another solution. I believe there is an easy and elegant solution that I'm not getting. Doing the select again with GROUP BY DESC is not an option.
Using a union is the only thing I can think of to accomplish this
select * from (select top(5) * from logins order by USERNAME ASC) a
union
select * from (select top(5) * from logins order by USERNAME DESC) b
Check the link
SQL SERVER – How to Retrieve TOP and BOTTOM Rows Together using T-SQL
Did you try to using rownumber?
SELECT *
FROM
(SELECT *, ROW_NUMBER() OVER (Order BY columnName) as TopFive
,ROW_NUMBER() OVER (Order BY columnName Desc) as BottomFive
FROM Table
)
WHERE TopFive <=5 or BottomFive <=5
http://www.sqlservercurry.com/2009/02/select-top-n-and-bottom-n-rows-using.html
I think you've two main options:
SELECT TOP 5 ...
FROM ...
ORDER BY ... ASC
UNION
SELECT TOP 5 ...
FROM ...
ORDER BY ... DESC
Or, if you know how many items there are in the table:
SELECT ...
FROM (
SELECT ..., ROW_NUMBER() OVER (ORDER BY ... ASC) AS intRow
FROM ...
) AS T
WHERE intRow BETWEEN 1 AND 5 OR intRow BETWEEN #Number - 5 AND #Number
Is it an option for you to use a union?
E.g.
select top 5 ... order by {specify columns asc}
union
select top 5 ... order by {specify columns desc}
i guess you have to do it using subquery only
select * from table where id in (
(SELECT id ORDER BY columnName LIMIT 5) OR
(SELECT id ORDER BY columnName DESC LIMIT 5)
)
select * from table where id in (
(SELECT TOP(5) id ORDER BY columnName) OR
(SELECT TOP(5) id ORDER BY columnName DESC)
)
EDITED
select * from table where id in (
(SELECT TOP 5 id ORDER BY columnName) OR
(SELECT TOP 5 id ORDER BY columnName DESC)
)
No real difference between this and the union that I'm aware of, but technically it is a single query.
select t.*
from table t
where t.id in (select top 5 t2.id from table t2 order by MyColumn)
or
t.id in (select top 5 t2.id from table t2 order by MyColumn desc);
SELECT *
FROM (
SELECT x, rank() over (order by x asc) as rown
FROM table
) temp
where temp.rown = 1
or temp.rown = (select count(x) from table)
Then you are out - doing the select again IS the only option, unless you want to pull in the complete result set and then throwing away everything in between.
ANY sql I cna think of is the same way - for the bottom you need to know first either how many items you have (materialize everything or use count(*)) or a reverse sort order.
Sorry if that does not suit you, but at the end.... reality does not care, and I do not see any other way to do that.
I had to do this recently for a very large stored procedure; if your query is quite large, and you want to minimize the amount of queries you could declare a #tempTable, insert into that #tempTable then query from that #tempTable,
DECLARE #tempTable TABLE ( columns.. )
INSERT INTO #tempTable
VALUES ( SELECT.. your query here ..)
SELECT TOP(5) columns FROM #tempTable ORDER BY column ASC -- returns first to last
SELECT TOP(5) columns FROM #tempTable ORDER BY column DESC -- returns last to first