I have a query where I'm trying to select a Row Number from a table that meets a certain criteria from a separate table.
The current query returns 0 results when I'm expecting 1 number
SELECT
RowNum
FROM
(SELECT
ID, Name, RowNum = ROW_NUMBER() OVER (ORDER BY ID)
FROM
tblEncroachmentTypes) AS temp
WHERE
temp.Name LIKE (SELECT EN_TYPE
FROM LakeEncroachments
WHERE EN_ID = '0526')
I have created a temp table to try and simplify it, but it still returns no results
select RowNum
from #temp1
where #temp1.Name like (select EN_TYPE from LakeEncroachments where EN_ID = '0526')
I'm trying to give as much information as possible, but not sure what else I need.
If you need to use like, you might need to add the wildcards:
SELECT RowNum
from (Select ID, Name, RowNum = ROW_NUMBER() over (order by ID) from tblEncroachmentTypes) as temp
where temp.Name Like '%'+(Select EN_TYPE from LakeEncroachments WHERE EN_ID = '0526')+'%'
reformat looks like this:
select RowNum
from (
select ID
, name
, RowNum = row_number() over (
order by ID
)
from tblEncroachmentTypes
) as temp
where temp.name like '%' + (
select EN_TYPE
from LakeEncroachments
where EN_ID = '0526'
) + '%'
Also, if your sub query for like returns more than one value, you'll need a different approach.
if your subquery give multiple rows, use this query
WITH temp as
(SELECT ID, Name, ROW_NUMBER() OVER (ORDER BY ID) as RowNum
FROM tblEncroachmentTypes) AS temp
SELECT temp.RowNum
FROM LakeEncroachments
INNER JOIN temp ON temp.Name LIKE REPLACE(REPLACE(LakeEncroachments.EN_TYPE, '-', '% '), ' ', '% ') + '%'
WHERE EN_ID = '0526'
Related
how to remove other rows with same Word in the SQL Table column
For example
StudentUserID SessionID
DSteve 101
DSteve 102
CJohn 101
For Reporting purpose we only need first ever row with StudentUserID
You can get the first row that has no overlap with other rows:
select t.*
from t
where not exists (select 1
from t t2
where (t2.name like '%' + t.name + '%' or
t.name like '%' + t2.name + '%'
) and
t2.SessionID < t.SessionID
);
This seems to be technically what you are asking for. It is not clear that this is actually useful.
EDIT:
For your revised question, I'll use a similar query:
select t.*
from t
where not exists (select 1
from t t2
where t2.StudentUserId = t2.StudentuserId and
t2.SessionID < t.SessionID
);
or make it otherwise
WITH b AS (SELECT t.*,
row_number() over(partition by student_name order by student_name ) as _rnk
from t )
SELECT * FROM b WHERE _rnk=1
although the purpose of that reporting is questionable :)
this will give you a unique student name output others will be dropped
but normally you would want to have a unique id for each student because there can be
multiple John Smiths etc.
You can use row_number() :
select t.*
from (select t.*,
row_number() over (partition by StudentUserID order by SessionID) as seq
from table t
) t
where seq = 1;
I want to count the total number of characters in a table.
I know how to do it for one column:
select sum(leng)
from (
select len(column) as leng
from table
) as Total
But how do I do this for every column in a table?
One way I have thought of is
select sum(len(col1) + len(col2) + len(3) + ...) as TotalChracters
from Table
But I need to do this for over 500 tables, and each table has a lot of columns. I was hoping for a general code that works for one table which I can easily loop over in Python by just changing the table name on each loop.
I have some code that does not run the query but it is almost the same as it will the desired code for any number of tables and columns in your DB.
Also, includes the ISNULL, so, if the table is empty it will show 0:
WITH CTE AS (
SELECT T.Name as Table_Name,
C.Name as Column_Name,
ROW_NUMBER() OVER (PARTITION BY T.Name ORDER BY T.Name, C.Name) AS RowASC,
ROW_NUMBER() OVER (PARTITION BY T.Name ORDER BY T.Name, C.Name DESC) AS RowDESC
FROM sysobjects T
INNER JOIN syscolumns C
ON T.ID = C.ID
WHERE T.XType = 'U'
)
SELECT *,
CASE WHEN RowASC = 1 THEN 'SELECT ISNULL(SUM(' ELSE '' END +
CASE WHEN RowASC = 1 THEN 'LEN('+Column_Name+')' ELSE '+LEN('+Column_Name+')' END +
CASE WHEN RowDESC = 1 THEN '), 0) AS [TotalCharacters on Table: '+Table_Name+']
FROM '+Table_Name +' UNION ' ELSE '' END AS Query
FROM CTE
ORDER BY Table_Name, Column_Name;
Just need to copy the column at the Right (Query) and paste in a new query window.
I have a table where ID must be unique. There are some IDs that are not unique. How do I generate a new column which adds a sequence to this ID? I want to generate ID_new_generated in the table below
ID Company Name ID_new_generated
1 A 1
1 B 1_2
2 C 2
You can use a windowing function (e.g. Rank) to to generate an secondary ID, over each window defined by rows that have the same ID number, then just concatenate it to create the new one.
something like:
select
ID
, companyName
, rank() over(partition by ID ORDER BY companyName)
, concat(ID, '_', rank() over(partition by ID ORDER BY companyName)) as new_id
from test;
See this demo: https://www.db-fiddle.com/f/bd6aQKnZ7gcZCQjFpZicrp/0
Syntax will be different depending on which sql you are using.
Assumed you are looking for a solution in SQL Server:
First you will need to add a nullable column ID_Generated like below:
ALTER TABLE tablename
ADD COLUMN ID_Generated varchar(25) null
GO
Then, use row_number like below in a cte structure (you can use temp table if you are using mysql):
;with cte as (
SELECT DISTINCT t.ID,
(ROW_NUMBER() over (partition by t.ID order by t.ID)) as RowNumber
FROM tablename t
INNER JOIN (select ID, Count(*) RecCount
From tablename
group by ID
having Count(*) > 1) tt on t.ID = t.ID
ORDER BY id ASC
)
Update t
set t.ID_Generated = cte.RowNumber
from tablename t
inner join cte on t.ID = cte.ID
I think you want:
select ID, companyName,
(case when row_number() over (partition by id order by companyname) = 1
then cast(id as varchar(255))
else id || '_' || row_number() over (partition by id order by companyname)
end) as new_id
from test;
|| is the ANSI/ISO standard concatenation operator in SQL. Not all databases support it, so you might need to replace the operator with the one appropriate for your database.
I have this query:
Select *
from
(Select
*
ROW_NUMBER() OVER (PARTITION BY TID ORDER BY TID) AS RowNumber
from
MyTable
where
Eid = 'C1') as a
where
a.RowNumber = 1
and it displays these results:
Column1 Column2 RowNumber
------------------------------
Value1 value2 1
I want to ignore the RowNumber column in the select statement and I don't want to list all columns in select query (100+ columns and given is just an example).
How to do this in SQL Server?
Well, you would have to list all the columns in the outer select, if you use a subquery and row_number() to get a unique row.
An alternative method uses a correlated subquery, but requires having some unique column in the table. If you have one:
select t.*
from mytable t
where t.col = (select max(t2.col) from mytable t2 where t2.tid = t.tid and t2.eid = 'C1');
With the right indexes, this can have better performance than the row_number() version.
If you don't have a unique column, you can do:
select t.*
from (select distinct tid from mytable where eid = 'C1') tc cross apply
(select top 1 t.*
from mytable t
where t.tid = tc.tid and t.eid = 'C1'
) t;
Wrap your query as a subquery and select specific columns from it like so:
SELECT x.Column1, x.Column2
FROM
(
Select * from (Select * ROW_NUMBER() OVER (PARTITION BY TID ORDER BY TID)
AS RowNumber from MyTable where Eid="C1") as a where a.RowNumber=1
) AS x
OR Change your original Select to:
Select a.[Column1], a.[Column2]
from
(
Select * ROW_NUMBER() OVER (PARTITION BY TID ORDER BY TID)
AS RowNumber from MyTable where Eid="C1"
) as a
Where a.RowNumber=1
Replace * from your query in clarify exactly columnd which you whant
select x.Column1, x.Column2 FROM (
Select * from (Select * ROW_NUMBER() OVER (PARTITION BY TID ORDER BY TID)
AS RowNumber from MyTable where Eid="C1") as a where a.RowNumber=1) AS x
I have a table that has columns ID, FIELD1, FIELD2, all of type NUMBER.
I want to find the MAX of a function on FIELD1 and FIELD2, and display that alongside the ID.
I try
SELECT ID, MAX(SQRT(FIELD1 + FIELD2)) AS CALC
FROM TABLE;
But it returns ORA-00937: not a single-group group function.
I tried the solutions in this thread, but they have their own errors.
SELECT * FROM (
SELECT ID, SQRT(FIELD1 + FIELD2) AS CALC,
RANK() OVER (ORDER BY CALC DESC) AS RANKING
FROM TABLE
)
WHERE RANKING = 1;
gives the error
ORA-06553: PLS-306: wrong number or types of arguments in call to
'OGC_CALC'
and so does
SELECT ID, SQRT(FIELD1 + FIELD2) AS CALC
FROM TABLE
WHERE CALC = (
SELECT MAX(CALC)
FROM TABLE
);
Using Oracle Database 11g Express Edition Release 11.2.0.2.0.
How can I get this to work? Thanks.
Can you try the below two queries.
SELECT ID,FIELD1,FIELD2,SQRT(FIELD1 + FIELD2) AS CALC
FROM TABLE WHERE SQRT(FIELD1 + FIELD2)= (SELECT MAX(SQRT(FIELD1 + FIELD2)) FROM TABLE);
Or,
Suggested by Aleksej without using aggregate or group by function.
SELECT *
FROM (
SELECT ID,
SQRT(FIELD1 + FIELD2)
FROM TABLE
ORDER BY 2 DESC
)
WHERE ROWNUM=1;
Initial query,
SELECT *
FROM (
SELECT ID,
MAX(SQRT(FIELD1 + FIELD2)) AS CALC
FROM TABLE
GROUP BY ID
ORDER BY 2 DESC
)
WHERE ROWNUM=1;
If you need a single value, with the maximum sqrt(field1+field2) among all the values of ID, these are two possible ways:
select *
from (
select *
from yourTable
order by sqrt(field1 + field2) desc
)
where rownum = 1
select id, field1, field2
from (
select t.*,
row_number() over ( order by sqrt(field1 + field2) desc) as rn
from yourTable t
)
where rn = 1
Notice that if you have more than one ID with the same, maximum value, this will pick one of them randomly.