reuse table alias in another select - sql

I have a sql statement:
select id from table1 t1, table t2
where.....
order by ( select count(owner_id) from t2) ASC;
What I want to do here is to select the id of the item whose owner has least number of items.
Is this possible? If not, what I can do to achieve to goal?
Thanks in advance!

You don't mention what SQL you're using but you can do this, or something similar, in PL ( and My I believe ); I'm assuming you're linking table 1 and 2 on id; I haven't ordered by the count(owner_id) alone as this will always be the same value. Obviously partition by whatever you want to get the correct count you're after.
select id
from ( select t1.id, t2.ct
from table1 t1
, ( select id, count(owner_id) over ( partition by id ) as ct
from table2 ) t2
where t1.id = t2.id
order by t2.ct ASC )
;

Related

How to get Full Record with MAX as aggregate function

I have a table with schema (id, date, value, source, ticker). I wanted to get record having highest ID group by date in sql server
Example Data
ID|date|value|source|ticker
3|10-Dec-2017|10|a|b
1|10-Dec-2017|11|p|q
Below query works in Sqlite. Do we know if I can do same with SqlServer
select max(id), date, value, source, ticker from table group by date
Expected return:-
ID|date|value|source|ticker
3|10-Dec-2017|10|a|b
Also how I can do same operation on UNION of 2 tables with same schema.
You can use subquery :
select t.*
from table t
where id = (select max(t1.id) from table t1 where t1.date = t.date);
However, you can also use row_number() function :
select top (1) with ties *
from table t
order by row_number() over (partition by [date] order by id desc);
You can also do it like below :
select t1.* from table1 t1
join (
select max(id) as id, [date] from table1
group by [date]
) as t2 on t1.id = t2.id
SQL HERE

Select duplicated data from table

Query
select * from table1
where having count(reference)>1
I want to select * the data which have duplicate data,any idea why my query is not working?
Below are my expect result..
You can make use of window function count to find number of rows per id and reference and then filter to get those which have count more than 1.
;with cte as (
select t.*, count(*) over (partition by id, reference) cnt
from table1 t
)
select * from cte where cnt > 1;
Demo
In the above solution, I have made an assumption that name and id has one to one correspondence (which is true as per your given data). If that's not the case, add name too in the partition by clause:
;with cte as (
select t.*, count(*) over (partition by name, id, reference) cnt
from table1 t
)
select * from cte where cnt > 1;
I might actually approach this by using a subquery with GROUP BY:
SELECT t1.*
FROM table1 t1
INNER JOIN
(
SELECT Name, ID, reference
FROM table1
GROUP BY Name, ID, reference
HAVING COUNT(*) > 1
) t2
ON t1.Name = t2.Name AND
t1.ID = t2.ID AND
t1.reference = t2.reference
Demo here:
Rextester
Try this ), first i get count by partition, after that i get row with count > 1
select No, Name, ID, Reference
from (select count(*) over (partition by name, ID, reference) cnt, table1.* from table1)
where cnt>1
The easy way (although maybe not the best for performance) would be:
select * from table1 where reference in (
select reference from table1 group by reference having count(*)>1
)
In a subselect you have the duplicated data, and in the outter select you have all the data for these references.

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

Delete duplicate rows not based on primary key

I have this table in my database:
tblAgencies
----------------------
AgencyID (PK)
VendorID
RegionID
Name
Zip
Long story short, I accidentally copied my entire table into itself - so every row in my table has a duplicate.
But with my AgencyID field being the identity, and automatically incrementing, I need to find duplicates based on all the other fields, since AgencyID is unique.
Does anyone know how I can do this?
This will keep the oldest AgencyID values, and delete any duplicates otherwise.
;WITH x AS
(
SELECT *, rn = ROW_NUMBER() OVER
(PARTITION BY VendorID, RegionID, Name, Zip
ORDER BY AgencyID) FROM dbo.tblAgencies
)
DELETE x WHERE rn > 1;
Be careful, though; this may not work if other tables reference AgencyID and they've obtained any of your newer, erroneous values.
The simplest solution, use select distinct into a temp table, then reload the original
This query will give you duplicates provided that the combination of all other columns is unique:
select * from mytable t1
where exists
(select * from mytable t2
where t1.VendorID = t2.VendorID
and t1.RegionID = t2.RegionID
and and t1.Name = t2.Name
and t1.Zip = t2.Zip
and t1.AgencyID > t2.AgencyID)
This should give you all the rows that have duplicate values except for the minimum agencyid row.
select *
from tblAgencies
where AgencyID not in (select min(AgencyID)
from tblAgencies
group by VendorID, RegionID, Name, Zip)
edit: adding SQLFiddle
;with CTE
AS
(
SELECT ID_Column, rn = ROW_NUMBER() OVER (PARTITION BY Column1, Column2, Column3... ORDER BY ID ASC)
FROM T
)
DELETE FROM CTE
WHERE rn >= 2
;with CTE
AS
(SELECT MAX(AgencyID) AgentID,VendorID ,
RegionID ,
Name ,
Zip FROM tblAgencies
GROUP BY VendorID ,
RegionID ,
Name ,
Zip
HAVING COUNT(*) > 1)
DELETE FROM tblAgencies WHERE EXISTS (SELECT 1 FROM CTE
WHERE AgentID = tblAgencies.AgencyID)
Lots of answers that will give you what you want here, but there's no need to use a CTE or do any grouping, the simplest way is just:
delete t1
from tblAgencies t1
join tblAgencies t2
on t1.VendorId = t2.VendorId
and t1.RegionId = t2.RegionId
and t1.Name = t2.Name
and t1.Zip = t2.Zip
and t1.AgencyId > t2.AgencyId
Maybe this will help: How to delete duplicates in the presence of a primary key?

PostgreSQL Selecting Most Recent Entry for a Given ID

Table Essentially looks like:
Serial-ID, ID, Date, Data, Data, Data, etc.
There can be Multiple Rows for the Same ID. I'd like to create a view of this table to be used in Reports that only shows the most recent entry for each ID. It should show all of the columns.
Can someone help me with the SQL select? thanks.
There's about 5 different ways to do this, but here's one:
SELECT *
FROM yourTable AS T1
WHERE NOT EXISTS(
SELECT *
FROM yourTable AS T2
WHERE T2.ID = T1.ID AND T2.Date > T1.Date
)
And here's another:
SELECT T1.*
FROM yourTable AS T1
LEFT JOIN yourTable AS T2 ON
(
T2.ID = T1.ID
AND T2.Date > T1.Date
)
WHERE T2.ID IS NULL
One more:
WITH T AS (
SELECT *, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY Date DESC) AS rn
FROM yourTable
)
SELECT * FROM T WHERE rn = 1
Ok, i'm getting carried away, here's the last one I'll post(for now):
WITH T AS (
SELECT ID, MAX(Date) AS latest_date
FROM yourTable
GROUP BY ID
)
SELECT yourTable.*
FROM yourTable
JOIN T ON T.ID = yourTable.ID AND T.latest_date = yourTable.Date
I would use DISTINCT ON
CREATE VIEW your_view AS
SELECT DISTINCT ON (id) *
FROM your_table a
ORDER BY id, date DESC;
This works because distinct on suppresses rows with duplicates of the expression in parentheses. DESC in order by means the one that normally sorts last will be first, and therefor be the one that shows in the result.
https://www.postgresql.org/docs/10/static/sql-select.html#SQL-DISTINCT
This seems like a good use for correlated subqueries:
CREATE VIEW your_view AS
SELECT *
FROM your_table a
WHERE date = (
SELECT MAX(date)
FROM your_table b
WHERE b.id = a.id
)
Your date column would need to uniquely identify each row (like a TIMESTAMP type).